summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/gtk/tests
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/gtk/tests')
-rw-r--r--Source/WebKit/gtk/tests/resources/blank.icobin0 -> 198 bytes
-rw-r--r--Source/WebKit/gtk/tests/resources/test.html6
-rw-r--r--Source/WebKit/gtk/tests/resources/test.oggbin0 -> 30131 bytes
-rw-r--r--Source/WebKit/gtk/tests/resources/test.pdfbin0 -> 7421 bytes
-rw-r--r--Source/WebKit/gtk/tests/resources/test.txt1
-rw-r--r--Source/WebKit/gtk/tests/test_utils.c50
-rw-r--r--Source/WebKit/gtk/tests/test_utils.h3
-rw-r--r--Source/WebKit/gtk/tests/testatk.c1345
-rw-r--r--Source/WebKit/gtk/tests/testatkroles.c428
-rw-r--r--Source/WebKit/gtk/tests/testcopyandpaste.c276
-rw-r--r--Source/WebKit/gtk/tests/testdomdocument.c375
-rw-r--r--Source/WebKit/gtk/tests/testdomdomwindow.c229
-rw-r--r--Source/WebKit/gtk/tests/testdomnode.c206
-rw-r--r--Source/WebKit/gtk/tests/testdownload.c272
-rw-r--r--Source/WebKit/gtk/tests/testglobals.c66
-rw-r--r--Source/WebKit/gtk/tests/testhittestresult.c174
-rw-r--r--Source/WebKit/gtk/tests/testhttpbackend.c86
-rw-r--r--Source/WebKit/gtk/tests/testkeyevents.c402
-rw-r--r--Source/WebKit/gtk/tests/testloading.c445
-rw-r--r--Source/WebKit/gtk/tests/testmimehandling.c228
-rw-r--r--Source/WebKit/gtk/tests/testnetworkrequest.c107
-rw-r--r--Source/WebKit/gtk/tests/testnetworkresponse.c108
-rw-r--r--Source/WebKit/gtk/tests/testwebbackforwardlist.c337
-rw-r--r--Source/WebKit/gtk/tests/testwebdatasource.c253
-rw-r--r--Source/WebKit/gtk/tests/testwebframe.c231
-rw-r--r--Source/WebKit/gtk/tests/testwebhistoryitem.c81
-rw-r--r--Source/WebKit/gtk/tests/testwebplugindatabase.c89
-rw-r--r--Source/WebKit/gtk/tests/testwebresource.c342
-rw-r--r--Source/WebKit/gtk/tests/testwebsettings.c81
-rw-r--r--Source/WebKit/gtk/tests/testwebview.c378
-rw-r--r--Source/WebKit/gtk/tests/testwindow.c130
31 files changed, 6729 insertions, 0 deletions
diff --git a/Source/WebKit/gtk/tests/resources/blank.ico b/Source/WebKit/gtk/tests/resources/blank.ico
new file mode 100644
index 0000000..ea848b9
--- /dev/null
+++ b/Source/WebKit/gtk/tests/resources/blank.ico
Binary files differ
diff --git a/Source/WebKit/gtk/tests/resources/test.html b/Source/WebKit/gtk/tests/resources/test.html
new file mode 100644
index 0000000..98f7d4f
--- /dev/null
+++ b/Source/WebKit/gtk/tests/resources/test.html
@@ -0,0 +1,6 @@
+<html>
+<head><title>test</title></head>
+<body>test</body>
+</html>></head>
+<body>test</body>
+</html>
diff --git a/Source/WebKit/gtk/tests/resources/test.ogg b/Source/WebKit/gtk/tests/resources/test.ogg
new file mode 100644
index 0000000..7f3a3b9
--- /dev/null
+++ b/Source/WebKit/gtk/tests/resources/test.ogg
Binary files differ
diff --git a/Source/WebKit/gtk/tests/resources/test.pdf b/Source/WebKit/gtk/tests/resources/test.pdf
new file mode 100644
index 0000000..2424c19
--- /dev/null
+++ b/Source/WebKit/gtk/tests/resources/test.pdf
Binary files differ
diff --git a/Source/WebKit/gtk/tests/resources/test.txt b/Source/WebKit/gtk/tests/resources/test.txt
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/Source/WebKit/gtk/tests/resources/test.txt
@@ -0,0 +1 @@
+test
diff --git a/Source/WebKit/gtk/tests/test_utils.c b/Source/WebKit/gtk/tests/test_utils.c
new file mode 100644
index 0000000..646fd25
--- /dev/null
+++ b/Source/WebKit/gtk/tests/test_utils.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Arno Renevier
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "test_utils.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+int testutils_relative_chdir(const gchar* target_filename, const gchar* executable_path)
+{
+ if (g_path_is_absolute(executable_path)) {
+ if (g_chdir(g_path_get_dirname(executable_path))) {
+ return -1;
+ }
+ }
+
+ while (!g_file_test(target_filename, G_FILE_TEST_EXISTS)) {
+ gchar *path_name;
+ if (g_chdir("..")) {
+ return -1;
+ }
+ g_assert(!g_str_equal((path_name = g_get_current_dir()), "/"));
+ g_free(path_name);
+ }
+
+ gchar* dirname = g_path_get_dirname(target_filename);
+ if (g_chdir(dirname)) {
+ g_free(dirname);
+ return -1;
+ }
+
+ g_free(dirname);
+ return 0;
+}
diff --git a/Source/WebKit/gtk/tests/test_utils.h b/Source/WebKit/gtk/tests/test_utils.h
new file mode 100644
index 0000000..e761f74
--- /dev/null
+++ b/Source/WebKit/gtk/tests/test_utils.h
@@ -0,0 +1,3 @@
+#include <glib.h>
+
+int testutils_relative_chdir(const gchar*, const gchar*);
diff --git a/Source/WebKit/gtk/tests/testatk.c b/Source/WebKit/gtk/tests/testatk.c
new file mode 100644
index 0000000..1ee6c55
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testatk.c
@@ -0,0 +1,1345 @@
+/*
+ * Copyright (C) 2009 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <unistd.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static const char* centeredContents = "<html><body><p style='text-align: center;'>Short line</p><p style='text-align: center;'>Long-size line with some foo bar baz content</p><p style='text-align: center;'>Short line</p><p style='text-align: center;'>This is a multi-line paragraph<br />where the first line<br />is the biggest one</p></body></html>";
+
+static const char* contents = "<html><body><p>This is a test. This is the second sentence. And this the third.</p></body></html>";
+
+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>";
+
+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>";
+
+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>";
+
+static const char* contentsInParagraphAndBodySimple = "<html><body><p>This is a test.</p>Hello world.</body></html>";
+
+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>";
+
+static const char* contentsInTable = "<html><body><table><tr><td>foo</td><td>bar</td></tr></table></body></html>";
+
+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>";
+
+static const char* comboBoxSelector = "<html><body><select><option selected value='foo'>foo</option><option value='bar'>bar</option></select></body></html>";
+
+static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>";
+
+static const char* hypertextAndHyperlinks = "<html><body><p>A paragraph with no links at all</p><p><a href='http://foo.bar.baz/'>A line</a> with <a href='http://bar.baz.foo/'>a link in the middle</a> as well as at the beginning and <a href='http://baz.foo.bar/'>at the end</a></p></body></html>";
+
+static const char* layoutAndDataTables = "<html><body><table><tr><th>Odd</th><th>Even</th></tr><tr><td>1</td><td>2</td></tr></table><table><tr><td>foo</td><td>bar</td></tr></table></body></html>";
+
+static const char* linksWithInlineImages = "<html><head><style>a.http:before {content: url(no-image.png);}</style><body><p><a class='http' href='foo'>foo</a> bar baz</p><p>foo <a class='http' href='bar'>bar</a> baz</p><p>foo bar <a class='http' href='baz'>baz</a></p></body></html>";
+
+static const char* listsOfItems = "<html><body><ul><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ul><ol><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ol></body></html>";
+
+static const char* textForSelections = "<html><body><p>A paragraph with plain text</p><p>A paragraph with <a href='http://webkit.org'>a link</a> in the middle</p></body></html>";
+
+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>";
+
+static void waitForAccessibleObjects()
+{
+ /* Manually spin the main context to make sure the accessible
+ objects are properly created before continuing. */
+ while (g_main_context_pending(0))
+ g_main_context_iteration(0, TRUE);
+}
+
+typedef gchar* (*AtkGetTextFunction) (AtkText*, gint, AtkTextBoundary, gint*, gint*);
+
+static void testGetTextFunction(AtkText* textObject, AtkGetTextFunction fn, AtkTextBoundary boundary, gint offset, const char* textResult, gint startOffsetResult, gint endOffsetResult)
+{
+ gint startOffset;
+ gint endOffset;
+ char* text = fn(textObject, offset, boundary, &startOffset, &endOffset);
+ g_assert_cmpstr(text, ==, textResult);
+ g_assert_cmpint(startOffset, ==, startOffsetResult);
+ g_assert_cmpint(endOffset, ==, endOffsetResult);
+ g_free(text);
+}
+
+static void runGetTextTests(AtkText* textObject)
+{
+ char* text = atk_text_get_text(textObject, 0, -1);
+ g_assert_cmpstr(text, ==, "This is a test. This is the second sentence. And this the third.");
+ g_free(text);
+
+ /* ATK_TEXT_BOUNDARY_CHAR */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_CHAR,
+ 0, "T", 0, 1);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_CHAR,
+ 0, "h", 1, 2);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR,
+ 0, "", 0, 0);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_CHAR,
+ 1, "T", 0, 1);
+
+ /* ATK_TEXT_BOUNDARY_WORD_START */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 0, "This ", 0, 5);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 4, "This ", 0, 5);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 10, "test. ", 10, 16);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 58, "third.", 58, 64);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 5, "This ", 0, 5);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 7, "This ", 0, 5);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 0, "is ", 5, 8);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 4, "is ", 5, 8);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_START,
+ 3, "is ", 5, 8);
+
+ /* ATK_TEXT_BOUNDARY_WORD_END */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 0, "This", 0, 4);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 4, " is", 4, 7);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 5, " is", 4, 7);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 9, " test", 9, 14);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 5, "This", 0, 4);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 4, "This", 0, 4);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 7, " is", 4, 7);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 5, " a", 7, 9);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 4, " a", 7, 9);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
+ 58, " third", 57, 63);
+
+ /* ATK_TEXT_BOUNDARY_SENTENCE_START */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 0, "This is a test. ", 0, 16);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 15, "This is a test. ", 0, 16);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 0, "This is the second sentence. ", 16, 45);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 15, "This is the second sentence. ", 16, 45);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 16, "This is a test. ", 0, 16);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 44, "This is a test. ", 0, 16);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_START,
+ 15, "", 0, 0);
+
+ /* ATK_TEXT_BOUNDARY_SENTENCE_END */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 0, "This is a test.", 0, 15);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 15, " This is the second sentence.", 15, 44);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 16, " This is the second sentence.", 15, 44);
+
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 17, " This is the second sentence.", 15, 44);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 0, " This is the second sentence.", 15, 44);
+
+ testGetTextFunction(textObject, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 15, " And this the third.", 44, 64);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 16, "This is a test.", 0, 15);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 15, "This is a test.", 0, 15);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 14, "", 0, 0);
+
+ testGetTextFunction(textObject, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
+ 44, " This is the second sentence.", 15, 44);
+
+ /* It's trick to test these properly right now, since our a11y
+ implementation splits different lines in different a11y items. */
+ /* ATK_TEXT_BOUNDARY_LINE_START */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START,
+ 0, "This is a test. This is the second sentence. And this the third.", 0, 64);
+
+ /* ATK_TEXT_BOUNDARY_LINE_END */
+ testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END,
+ 0, "This is a test. This is the second sentence. And this the third.", 0, 64);
+}
+
+static void testWebkitAtkComboBox()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, comboBoxSelector, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ AtkObject* formObject = atk_object_ref_accessible_child(object, 0);
+ g_assert(formObject);
+
+ AtkObject* comboBox = atk_object_ref_accessible_child(formObject, 0);
+ g_assert(ATK_IS_OBJECT(comboBox));
+
+ AtkObject* menuPopup = atk_object_ref_accessible_child(comboBox, 0);
+ g_assert(ATK_IS_OBJECT(menuPopup));
+
+ AtkObject* item1 = atk_object_ref_accessible_child(menuPopup, 0);
+ g_assert(ATK_IS_OBJECT(item1));
+
+ AtkObject* item2 = atk_object_ref_accessible_child(menuPopup, 1);
+ g_assert(ATK_IS_OBJECT(item2));
+
+ /* Check roles. */
+ g_assert(atk_object_get_role(comboBox) == ATK_ROLE_COMBO_BOX);
+ g_assert(atk_object_get_role(menuPopup) == ATK_ROLE_MENU);
+ g_assert(atk_object_get_role(item1) == ATK_ROLE_MENU_ITEM);
+ g_assert(atk_object_get_role(item2) == ATK_ROLE_MENU_ITEM);
+
+ /* Check the implementation of the AtkSelection interface. */
+ g_assert(ATK_IS_SELECTION(comboBox));
+ AtkSelection* atkSelection = ATK_SELECTION(comboBox);
+ g_assert_cmpint(atk_selection_get_selection_count(atkSelection), ==, 1);
+ g_assert(atk_selection_is_child_selected(atkSelection, 0));
+ g_assert(!atk_selection_is_child_selected(atkSelection, 1));
+ AtkObject* selectedItem = atk_selection_ref_selection(atkSelection, 0);
+ g_assert(selectedItem == item1);
+ g_object_unref(selectedItem);
+
+ /* Check the implementations of the AtkAction interface. */
+ g_assert(ATK_IS_ACTION(comboBox));
+ AtkAction* atkAction = ATK_ACTION(comboBox);
+ g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
+ g_assert(atk_action_do_action(atkAction, 0));
+
+ g_assert(ATK_IS_ACTION(menuPopup));
+ atkAction = ATK_ACTION(menuPopup);
+ g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
+ g_assert(atk_action_do_action(atkAction, 0));
+
+ g_assert(ATK_IS_ACTION(item1));
+ atkAction = ATK_ACTION(item1);
+ g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
+ g_assert(atk_action_do_action(atkAction, 0));
+
+ g_assert(ATK_IS_ACTION(item2));
+ atkAction = ATK_ACTION(item2);
+ g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
+ g_assert(atk_action_do_action(atkAction, 0));
+
+ /* After selecting the second item, selection should have changed. */
+ g_assert_cmpint(atk_selection_get_selection_count(atkSelection), ==, 1);
+ g_assert(!atk_selection_is_child_selected(atkSelection, 0));
+ g_assert(atk_selection_is_child_selected(atkSelection, 1));
+ selectedItem = atk_selection_ref_selection(atkSelection, 0);
+ g_assert(selectedItem == item2);
+ g_object_unref(selectedItem);
+
+ /* Check the implementation of the AtkText interface. */
+ g_assert(ATK_IS_TEXT(item1));
+ AtkText* atkText = ATK_TEXT(item1);
+ char *text = atk_text_get_text(atkText, 0, -1);
+ g_assert_cmpstr(text, ==, "foo");
+ g_free(text);
+ text = atk_text_get_text(atkText, 0, 2);
+ g_assert_cmpstr(text, ==, "fo");
+ g_free(text);
+
+ g_assert(ATK_IS_TEXT(item2));
+ atkText = ATK_TEXT(item2);
+ text = atk_text_get_text(atkText, 0, -1);
+ g_assert_cmpstr(text, ==, "bar");
+ g_free(text);
+ text = atk_text_get_text(atkText, 1, 3);
+ g_assert_cmpstr(text, ==, "ar");
+ g_free(text);
+
+ g_object_unref(formObject);
+ g_object_unref(comboBox);
+ g_object_unref(menuPopup);
+ g_object_unref(item1);
+ g_object_unref(item2);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextAtOffsetForms()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contents, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+
+ AtkText* textObject = ATK_TEXT(object);
+ g_assert(ATK_IS_TEXT(textObject));
+
+ runGetTextTests(textObject);
+
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextAtOffset()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contents, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+
+ AtkText* textObject = ATK_TEXT(object);
+ g_assert(ATK_IS_TEXT(textObject));
+
+ runGetTextTests(textObject);
+
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextAtOffsetNewlines()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsWithNewlines, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+
+ AtkText* textObject = ATK_TEXT(object);
+ g_assert(ATK_IS_TEXT(textObject));
+
+ runGetTextTests(textObject);
+
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextAtOffsetTextarea()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsInTextarea, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+
+ AtkText* textObject = ATK_TEXT(object);
+ g_assert(ATK_IS_TEXT(textObject));
+
+ runGetTextTests(textObject);
+
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextAtOffsetTextInput()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsInTextInput, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+
+ AtkText* textObject = ATK_TEXT(object);
+ g_assert(ATK_IS_TEXT(textObject));
+
+ runGetTextTests(textObject);
+
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextInParagraphAndBodySimple()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsInParagraphAndBodySimple, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ AtkObject* object1 = atk_object_ref_accessible_child(object, 0);
+ g_assert(object1);
+ AtkObject* object2 = atk_object_ref_accessible_child(object, 1);
+ g_assert(object2);
+
+ AtkText* textObject1 = ATK_TEXT(object1);
+ g_assert(ATK_IS_TEXT(textObject1));
+ AtkText* textObject2 = ATK_TEXT(object2);
+ g_assert(ATK_IS_TEXT(textObject2));
+
+ char *text = atk_text_get_text(textObject1, 0, -1);
+ g_assert_cmpstr(text, ==, "This is a test.");
+
+ text = atk_text_get_text(textObject2, 0, 12);
+ g_assert_cmpstr(text, ==, "Hello world.");
+
+ g_object_unref(object1);
+ g_object_unref(object2);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextInParagraphAndBodyModerate()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsInParagraphAndBodyModerate, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ /* Get to the inner AtkText object. */
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ AtkObject* object1 = atk_object_ref_accessible_child(object, 0);
+ g_assert(object1);
+ AtkObject* object2 = atk_object_ref_accessible_child(object, 1);
+ g_assert(object2);
+
+ AtkText* textObject1 = ATK_TEXT(object1);
+ g_assert(ATK_IS_TEXT(textObject1));
+ AtkText* textObject2 = ATK_TEXT(object2);
+ g_assert(ATK_IS_TEXT(textObject2));
+
+ char *text = atk_text_get_text(textObject1, 0, -1);
+ g_assert_cmpstr(text, ==, "This is a test.");
+
+ text = atk_text_get_text(textObject2, 0, 53);
+ g_assert_cmpstr(text, ==, "Hello world.\nThis sentence is green.\nThis one is not.");
+
+ g_object_unref(object1);
+ g_object_unref(object2);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetTextInTable()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsInTable, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+ object = atk_object_ref_accessible_child(object, 0);
+ g_assert(object);
+
+ /* Tables should not implement AtkText. */
+ g_assert(!G_TYPE_INSTANCE_GET_INTERFACE(object, ATK_TYPE_TEXT, AtkTextIface));
+
+ g_object_unref(object);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetHeadersInTable()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, contentsInTableWithHeaders, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* axWebView = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(axWebView);
+
+ /* Check table with both column and row headers. */
+ AtkObject* table = atk_object_ref_accessible_child(axWebView, 0);
+ g_assert(table);
+ g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE);
+
+ AtkObject* colHeader = atk_table_get_column_header(ATK_TABLE(table), 0);
+ g_assert(colHeader);
+ g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(colHeader) == 0);
+
+ colHeader = atk_table_get_column_header(ATK_TABLE(table), 1);
+ g_assert(colHeader);
+ g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(colHeader) == 1);
+
+ colHeader = atk_table_get_column_header(ATK_TABLE(table), 2);
+ g_assert(colHeader);
+ g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(colHeader) == 2);
+
+ colHeader = atk_table_get_column_header(ATK_TABLE(table), 3);
+ g_assert(colHeader);
+ g_assert(atk_object_get_role(colHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(colHeader) == 2);
+
+ AtkObject* rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0);
+ g_assert(rowHeader);
+ g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(rowHeader) == 0);
+
+ rowHeader = atk_table_get_row_header(ATK_TABLE(table), 1);
+ g_assert(rowHeader);
+ g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(rowHeader) == 3);
+
+ rowHeader = atk_table_get_row_header(ATK_TABLE(table), 2);
+ g_assert(rowHeader);
+ g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(rowHeader) == 7);
+
+ rowHeader = atk_table_get_row_header(ATK_TABLE(table), 3);
+ g_assert(rowHeader);
+ g_assert(atk_object_get_role(rowHeader) == ATK_ROLE_TABLE_CELL);
+ g_assert(atk_object_get_index_in_parent(rowHeader) == 7);
+
+ g_object_unref(table);
+
+ /* Check table with no headers at all. */
+ table = atk_object_ref_accessible_child(axWebView, 1);
+ g_assert(table);
+ g_assert(atk_object_get_role(table) == ATK_ROLE_TABLE);
+
+ colHeader = atk_table_get_column_header(ATK_TABLE(table), 0);
+ g_assert(colHeader == 0);
+
+ colHeader = atk_table_get_column_header(ATK_TABLE(table), 1);
+ g_assert(colHeader == 0);
+
+ rowHeader = atk_table_get_row_header(ATK_TABLE(table), 0);
+ g_assert(rowHeader == 0);
+
+ rowHeader = atk_table_get_row_header(ATK_TABLE(table), 1);
+ g_assert(rowHeader == 0);
+
+ g_object_unref(table);
+ g_object_unref(webView);
+}
+
+static gint compAtkAttribute(AtkAttribute* a1, AtkAttribute* a2)
+{
+ gint strcmpVal = g_strcmp0(a1->name, a2->name);
+ if (strcmpVal)
+ return strcmpVal;
+ return g_strcmp0(a1->value, a2->value);
+}
+
+static gint compAtkAttributeName(AtkAttribute* a1, AtkAttribute* a2)
+{
+ return g_strcmp0(a1->name, a2->name);
+}
+
+static gboolean atkAttributeSetAttributeNameHasValue(AtkAttributeSet* set, const gchar* attributeName, const gchar* value)
+{
+ AtkAttribute at;
+ at.name = (gchar*)attributeName;
+ GSList* element = g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName);
+ return element && !g_strcmp0(((AtkAttribute*)(element->data))->value, value);
+}
+
+static gboolean atkAttributeSetContainsAttributeName(AtkAttributeSet* set, const gchar* attributeName)
+{
+ AtkAttribute at;
+ at.name = (gchar*)attributeName;
+ return g_slist_find_custom(set, &at, (GCompareFunc)compAtkAttributeName) ? true : false;
+}
+
+static gboolean atkAttributeSetAttributeHasValue(AtkAttributeSet* set, AtkTextAttribute attribute, const gchar* value)
+{
+ return atkAttributeSetAttributeNameHasValue(set, atk_text_attribute_get_name(attribute), value);
+}
+
+static gboolean atkAttributeSetAreEqual(AtkAttributeSet* set1, AtkAttributeSet* set2)
+{
+ if (!set1)
+ return !set2;
+
+ set1 = g_slist_sort(set1, (GCompareFunc)compAtkAttribute);
+ set2 = g_slist_sort(set2, (GCompareFunc)compAtkAttribute);
+
+ while (set1) {
+ if (!set2 || compAtkAttribute(set1->data, set2->data))
+ return FALSE;
+
+ set1 = set1->next;
+ set2 = set2->next;
+ }
+
+ return (!set2);
+}
+
+static void testWebkitAtkTextAttributes()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, textWithAttributes, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ AtkObject* child = atk_object_ref_accessible_child(object, 0);
+ g_assert(child && ATK_IS_TEXT(child));
+ AtkText* childText = ATK_TEXT(child);
+
+ gint startOffset;
+ gint endOffset;
+ AtkAttributeSet* set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 0);
+ g_assert_cmpint(endOffset, ==, 12);
+ g_assert(atkAttributeSetAreEqual(set1, 0));
+
+ AtkAttributeSet* set2 = atk_text_get_run_attributes(childText, 15, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 12);
+ g_assert_cmpint(endOffset, ==, 17);
+ g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_STYLE, "italic"));
+
+ AtkAttributeSet* set3 = atk_text_get_run_attributes(childText, 17, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 17);
+ g_assert_cmpint(endOffset, ==, 40);
+ g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_WEIGHT, "700"));
+
+ AtkAttributeSet* set4 = atk_text_get_default_attributes(childText);
+ g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_STYLE, "normal"));
+ g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_JUSTIFICATION, "right"));
+ g_assert(atkAttributeSetAttributeHasValue(set4, ATK_TEXT_ATTR_SIZE, "14"));
+ atk_attribute_set_free(set1);
+ atk_attribute_set_free(set2);
+ atk_attribute_set_free(set3);
+ atk_attribute_set_free(set4);
+
+ child = atk_object_ref_accessible_child(object, 1);
+ g_assert(child && ATK_IS_TEXT(child));
+ childText = ATK_TEXT(child);
+
+ set1 = atk_text_get_default_attributes(childText);
+ g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_FAMILY_NAME, "monospace"));
+ g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STYLE, "normal"));
+ g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STRIKETHROUGH, "false"));
+ g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_WEIGHT, "400"));
+ g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_FG_COLOR, "120,121,122"));
+
+ set2 = atk_text_get_run_attributes(childText, 43, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 43);
+ g_assert_cmpint(endOffset, ==, 80);
+ /* Checks that default attributes of text are not returned when called to atk_text_get_run_attributes. */
+ g_assert(!atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_FG_COLOR, "120,121,122"));
+ g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_UNDERLINE, "single"));
+ g_assert(atkAttributeSetAttributeHasValue(set2, ATK_TEXT_ATTR_BG_COLOR, "80,81,82"));
+ atk_attribute_set_free(set1);
+ atk_attribute_set_free(set2);
+
+ child = atk_object_ref_accessible_child(object, 2);
+ g_assert(child && ATK_IS_TEXT(child));
+ childText = ATK_TEXT(child);
+
+ set1 = atk_text_get_run_attributes(childText, 0, &startOffset, &endOffset);
+ set2 = atk_text_get_run_attributes(childText, 3, &startOffset, &endOffset);
+ g_assert(atkAttributeSetAreEqual(set1, set2));
+ atk_attribute_set_free(set2);
+
+ set2 = atk_text_get_run_attributes(childText, 1, &startOffset, &endOffset);
+ set3 = atk_text_get_run_attributes(childText, 5, &startOffset, &endOffset);
+ g_assert(atkAttributeSetAreEqual(set2, set3));
+ g_assert(!atkAttributeSetAreEqual(set1, set2));
+ atk_attribute_set_free(set3);
+
+ set3 = atk_text_get_run_attributes(childText, 2, &startOffset, &endOffset);
+ set4 = atk_text_get_run_attributes(childText, 6, &startOffset, &endOffset);
+ g_assert(atkAttributeSetAreEqual(set3, set4));
+ g_assert(!atkAttributeSetAreEqual(set1, set3));
+ g_assert(!atkAttributeSetAreEqual(set2, set3));
+ atk_attribute_set_free(set1);
+ atk_attribute_set_free(set2);
+ atk_attribute_set_free(set3);
+ atk_attribute_set_free(set4);
+
+ child = atk_object_ref_accessible_child(object, 3);
+ g_assert(child && ATK_IS_TEXT(child));
+ childText = ATK_TEXT(child);
+ set1 = atk_text_get_run_attributes(childText, 24, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 21);
+ g_assert_cmpint(endOffset, ==, 25);
+ g_assert(atkAttributeSetAttributeHasValue(set1, ATK_TEXT_ATTR_STRIKETHROUGH, "true"));
+
+ set2 = atk_text_get_run_attributes(childText, 25, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 25);
+ g_assert_cmpint(endOffset, ==, 30);
+ g_assert(atkAttributeSetAreEqual(set2, 0));
+
+ set3 = atk_text_get_default_attributes(childText);
+ g_assert(atkAttributeSetAttributeHasValue(set3, ATK_TEXT_ATTR_JUSTIFICATION, "center"));
+ atk_attribute_set_free(set1);
+ atk_attribute_set_free(set2);
+ atk_attribute_set_free(set3);
+}
+
+static void testWebkitAtkTextSelections()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, textForSelections, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0));
+ g_assert(ATK_IS_TEXT(paragraph1));
+ AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(object, 1));
+ g_assert(ATK_IS_TEXT(paragraph2));
+ AtkText* link = ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(paragraph2), 0));
+ g_assert(ATK_IS_TEXT(link));
+
+ /* First paragraph (simple text). */
+
+ /* Basic initial checks. */
+ g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0);
+
+ gint startOffset;
+ gint endOffset;
+ gchar* selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 0);
+ g_assert_cmpint(endOffset, ==, 0);
+ g_assert_cmpstr(selectedText, ==, 0);
+ g_free (selectedText);
+
+ /* Try removing a non existing (yet) selection. */
+ gboolean result = atk_text_remove_selection(paragraph1, 0);
+ g_assert(!result);
+
+ /* Try setting a 0-char selection. */
+ result = atk_text_set_selection(paragraph1, 0, 5, 5);
+ g_assert(result);
+
+ /* Make a selection and test it. */
+ result = atk_text_set_selection(paragraph1, 0, 5, 25);
+ g_assert(result);
+ g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 1);
+ selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 5);
+ g_assert_cmpint(endOffset, ==, 25);
+ g_assert_cmpstr(selectedText, ==, "agraph with plain te");
+ g_free (selectedText);
+ /* Try removing the selection from other AtkText object (should fail). */
+ result = atk_text_remove_selection(paragraph2, 0);
+ g_assert(!result);
+
+ /* Remove the selection and test everything again. */
+ result = atk_text_remove_selection(paragraph1, 0);
+ g_assert(result);
+ g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0);
+ selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset);
+ /* Now offsets should be the same, set to the last position of the caret. */
+ g_assert_cmpint(startOffset, ==, endOffset);
+ g_assert_cmpint(startOffset, ==, 25);
+ g_assert_cmpint(endOffset, ==, 25);
+ g_assert_cmpstr(selectedText, ==, 0);
+ g_free (selectedText);
+
+ /* Second paragraph (text + link + text). */
+
+ /* Set a selection partially covering the link and test it. */
+ result = atk_text_set_selection(paragraph2, 0, 7, 21);
+ g_assert(result);
+
+ /* Test the paragraph first. */
+ g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1);
+ selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 7);
+ g_assert_cmpint(endOffset, ==, 21);
+ g_assert_cmpstr(selectedText, ==, "raph with a li");
+ g_free (selectedText);
+
+ /* Now test just the link. */
+ g_assert_cmpint(atk_text_get_n_selections(link), ==, 1);
+ selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 0);
+ g_assert_cmpint(endOffset, ==, 4);
+ g_assert_cmpstr(selectedText, ==, "a li");
+ g_free (selectedText);
+
+ /* Make a selection after the link and check selection for the whole paragraph. */
+ result = atk_text_set_selection(paragraph2, 0, 27, 37);
+ g_assert(result);
+ g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1);
+ selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset);
+ g_assert_cmpint(startOffset, ==, 27);
+ g_assert_cmpint(endOffset, ==, 37);
+ g_assert_cmpstr(selectedText, ==, "the middle");
+ g_free (selectedText);
+
+ /* Remove selections and text everything again. */
+ result = atk_text_remove_selection(paragraph2, 0);
+ g_assert(result);
+ g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 0);
+ selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset);
+ /* Now offsets should be the same (no selection). */
+ g_assert_cmpint(startOffset, ==, endOffset);
+ g_assert_cmpstr(selectedText, ==, 0);
+ g_free (selectedText);
+
+ g_assert_cmpint(atk_text_get_n_selections(link), ==, 0);
+ selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset);
+ /* Now offsets should be the same (no selection). */
+ g_assert_cmpint(startOffset, ==, endOffset);
+ g_assert_cmpstr(selectedText, ==, 0);
+ g_free (selectedText);
+
+ g_object_unref(paragraph1);
+ g_object_unref(paragraph2);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkGetExtents()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, centeredContents, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ AtkText* shortText1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0));
+ g_assert(ATK_IS_TEXT(shortText1));
+ AtkText* longText = ATK_TEXT(atk_object_ref_accessible_child(object, 1));
+ g_assert(ATK_IS_TEXT(longText));
+ AtkText* shortText2 = ATK_TEXT(atk_object_ref_accessible_child(object, 2));
+ g_assert(ATK_IS_TEXT(shortText2));
+ AtkText* multilineText = ATK_TEXT(atk_object_ref_accessible_child(object, 3));
+ g_assert(ATK_IS_TEXT(multilineText));
+
+ /* Start with window extents. */
+ AtkTextRectangle sline_window1, sline_window2, lline_window, mline_window;
+ atk_text_get_range_extents(shortText1, 0, 10, ATK_XY_WINDOW, &sline_window1);
+ atk_text_get_range_extents(longText, 0, 44, ATK_XY_WINDOW, &lline_window);
+ atk_text_get_range_extents(shortText2, 0, 10, ATK_XY_WINDOW, &sline_window2);
+ atk_text_get_range_extents(multilineText, 0, 60, ATK_XY_WINDOW, &mline_window);
+
+ /* Check vertical line position. */
+ g_assert_cmpint(sline_window1.y + sline_window1.height, <=, lline_window.y);
+ g_assert_cmpint(lline_window.y + lline_window.height + sline_window2.height, <=, mline_window.y);
+
+ /* Paragraphs 1 and 3 have identical text and alignment. */
+ g_assert_cmpint(sline_window1.x, ==, sline_window2.x);
+ g_assert_cmpint(sline_window1.width, ==, sline_window2.width);
+ g_assert_cmpint(sline_window1.height, ==, sline_window2.height);
+
+ /* All lines should be the same height; line 2 is the widest line. */
+ g_assert_cmpint(sline_window1.height, ==, lline_window.height);
+ g_assert_cmpint(sline_window1.width, <, lline_window.width);
+
+ /* Make sure the character extents jive with the range extents. */
+ gint x;
+ gint y;
+ gint width;
+ gint height;
+
+ /* First paragraph (short text). */
+ atk_text_get_character_extents(shortText1, 0, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, sline_window1.x);
+ g_assert_cmpint(y, ==, sline_window1.y);
+ g_assert_cmpint(height, ==, sline_window1.height);
+
+ atk_text_get_character_extents(shortText1, 9, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, sline_window1.x + sline_window1.width - width);
+ g_assert_cmpint(y, ==, sline_window1.y);
+ g_assert_cmpint(height, ==, sline_window1.height);
+
+ /* Second paragraph (long text). */
+ atk_text_get_character_extents(longText, 0, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, lline_window.x);
+ g_assert_cmpint(y, ==, lline_window.y);
+ g_assert_cmpint(height, ==, lline_window.height);
+
+ atk_text_get_character_extents(longText, 43, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, lline_window.x + lline_window.width - width);
+ g_assert_cmpint(y, ==, lline_window.y);
+ g_assert_cmpint(height, ==, lline_window.height);
+
+ /* Third paragraph (short text). */
+ atk_text_get_character_extents(shortText2, 0, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, sline_window2.x);
+ g_assert_cmpint(y, ==, sline_window2.y);
+ g_assert_cmpint(height, ==, sline_window2.height);
+
+ atk_text_get_character_extents(shortText2, 9, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, sline_window2.x + sline_window2.width - width);
+ g_assert_cmpint(y, ==, sline_window2.y);
+ g_assert_cmpint(height, ==, sline_window2.height);
+
+ /* Four paragraph (3 lines multi-line text). */
+ atk_text_get_character_extents(multilineText, 0, &x, &y, &width, &height, ATK_XY_WINDOW);
+ g_assert_cmpint(x, ==, mline_window.x);
+ g_assert_cmpint(y, ==, mline_window.y);
+ g_assert_cmpint(3 * height, ==, mline_window.height);
+
+ atk_text_get_character_extents(multilineText, 59, &x, &y, &width, &height, ATK_XY_WINDOW);
+ /* Last line won't fill the whole width of the rectangle. */
+ g_assert_cmpint(x, <=, mline_window.x + mline_window.width - width);
+ g_assert_cmpint(y, ==, mline_window.y + mline_window.height - height);
+ g_assert_cmpint(height, <=, mline_window.height);
+
+ g_object_unref(shortText1);
+ g_object_unref(shortText2);
+ g_object_unref(longText);
+ g_object_unref(multilineText);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkLayoutAndDataTables()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, layoutAndDataTables, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ /* Check the non-layout table (data table). */
+
+ AtkObject* table1 = atk_object_ref_accessible_child(object, 0);
+ g_assert(ATK_IS_TABLE(table1));
+ AtkAttributeSet* set1 = atk_object_get_attributes(table1);
+ g_assert(set1);
+ g_assert(!atkAttributeSetContainsAttributeName(set1, "layout-guess"));
+ atk_attribute_set_free(set1);
+
+ /* Check the layout table. */
+
+ AtkObject* table2 = atk_object_ref_accessible_child(object, 1);
+ g_assert(ATK_IS_TABLE(table2));
+ AtkAttributeSet* set2 = atk_object_get_attributes(table2);
+ g_assert(set2);
+ g_assert(atkAttributeSetContainsAttributeName(set2, "layout-guess"));
+ g_assert(atkAttributeSetAttributeNameHasValue(set2, "layout-guess", "true"));
+ atk_attribute_set_free(set2);
+
+ g_object_unref(table1);
+ g_object_unref(table2);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkLinksWithInlineImages()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, linksWithInlineImages, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ /* First paragraph (link at the beginning). */
+ AtkObject* paragraph = atk_object_ref_accessible_child(object, 0);
+ g_assert(ATK_IS_TEXT(paragraph));
+ gint startOffset;
+ gint endOffset;
+ gchar* text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset);
+ g_assert(text);
+ g_assert_cmpstr(text, ==, "foo bar baz");
+ g_assert_cmpint(startOffset, ==, 0);
+ g_assert_cmpint(endOffset, ==, 11);
+ g_free(text);
+ g_object_unref(paragraph);
+
+ /* Second paragraph (link in the middle). */
+ paragraph = atk_object_ref_accessible_child(object, 1);
+ g_assert(ATK_IS_TEXT(paragraph));
+ text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset);
+ g_assert(text);
+ g_assert_cmpstr(text, ==, "foo bar baz");
+ g_assert_cmpint(startOffset, ==, 0);
+ g_assert_cmpint(endOffset, ==, 11);
+ g_free(text);
+ g_object_unref(paragraph);
+
+ /* Third paragraph (link at the end). */
+ paragraph = atk_object_ref_accessible_child(object, 2);
+ g_assert(ATK_IS_TEXT(paragraph));
+ text = atk_text_get_text_at_offset(ATK_TEXT(paragraph), 0, ATK_TEXT_BOUNDARY_LINE_START, &startOffset, &endOffset);
+ g_assert(text);
+ g_assert_cmpstr(text, ==, "foo bar baz");
+ g_assert_cmpint(startOffset, ==, 0);
+ g_assert_cmpint(endOffset, ==, 11);
+ g_free(text);
+ g_object_unref(paragraph);
+
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkHypertextAndHyperlinks()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, hypertextAndHyperlinks, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ AtkObject* paragraph1 = atk_object_ref_accessible_child(object, 0);
+ g_assert(ATK_OBJECT(paragraph1));
+ g_assert(atk_object_get_role(paragraph1) == ATK_ROLE_PARAGRAPH);
+ g_assert(ATK_IS_HYPERTEXT(paragraph1));
+
+ /* No links in the first paragraph. */
+ gint nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph1));
+ g_assert_cmpint(nLinks, ==, 0);
+
+ AtkObject* paragraph2 = atk_object_ref_accessible_child(object, 1);
+ g_assert(ATK_OBJECT(paragraph2));
+ g_assert(atk_object_get_role(paragraph2) == ATK_ROLE_PARAGRAPH);
+ g_assert(ATK_IS_HYPERTEXT(paragraph2));
+
+ /* Check links in the second paragraph.
+ nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph2));
+ g_assert_cmpint(nLinks, ==, 3); */
+
+ AtkHyperlink* hLink1 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 0);
+ g_assert(ATK_HYPERLINK(hLink1));
+ AtkObject* hLinkObject1 = atk_hyperlink_get_object(hLink1, 0);
+ g_assert(ATK_OBJECT(hLinkObject1));
+ g_assert(atk_object_get_role(hLinkObject1) == ATK_ROLE_LINK);
+ g_assert_cmpint(atk_hyperlink_get_start_index(hLink1), ==, 0);
+ g_assert_cmpint(atk_hyperlink_get_end_index(hLink1), ==, 6);
+ g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink1), ==, 1);
+ g_assert_cmpstr(atk_hyperlink_get_uri(hLink1, 0), ==, "http://foo.bar.baz/");
+
+ AtkHyperlink* hLink2 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 1);
+ g_assert(ATK_HYPERLINK(hLink2));
+ AtkObject* hLinkObject2 = atk_hyperlink_get_object(hLink2, 0);
+ g_assert(ATK_OBJECT(hLinkObject2));
+ g_assert(atk_object_get_role(hLinkObject2) == ATK_ROLE_LINK);
+ g_assert_cmpint(atk_hyperlink_get_start_index(hLink2), ==, 12);
+ g_assert_cmpint(atk_hyperlink_get_end_index(hLink2), ==, 32);
+ g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink2), ==, 1);
+ g_assert_cmpstr(atk_hyperlink_get_uri(hLink2, 0), ==, "http://bar.baz.foo/");
+
+ AtkHyperlink* hLink3 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 2);
+ g_assert(ATK_HYPERLINK(hLink3));
+ AtkObject* hLinkObject3 = atk_hyperlink_get_object(hLink3, 0);
+ g_assert(ATK_OBJECT(hLinkObject3));
+ g_assert(atk_object_get_role(hLinkObject3) == ATK_ROLE_LINK);
+ g_assert_cmpint(atk_hyperlink_get_start_index(hLink3), ==, 65);
+ g_assert_cmpint(atk_hyperlink_get_end_index(hLink3), ==, 75);
+ g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink3), ==, 1);
+ g_assert_cmpstr(atk_hyperlink_get_uri(hLink3, 0), ==, "http://baz.foo.bar/");
+
+ /* Finally check the AtkAction interface for a given AtkHyperlink. */
+ g_assert(ATK_IS_ACTION(hLink1));
+ g_assert_cmpint(atk_action_get_n_actions(ATK_ACTION(hLink1)), ==, 1);
+ g_assert_cmpstr(atk_action_get_keybinding(ATK_ACTION(hLink1), 0), ==, "");
+ g_assert_cmpstr(atk_action_get_name(ATK_ACTION(hLink1), 0), ==, "jump");
+ g_assert(atk_action_do_action(ATK_ACTION(hLink1), 0));
+
+ g_object_unref(paragraph1);
+ g_object_unref(paragraph2);
+ g_object_unref(webView);
+}
+
+static void testWebkitAtkListsOfItems()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, listsOfItems, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ /* Unordered list. */
+
+ AtkObject* uList = atk_object_ref_accessible_child(object, 0);
+ g_assert(ATK_OBJECT(uList));
+ g_assert(atk_object_get_role(uList) == ATK_ROLE_LIST);
+ g_assert_cmpint(atk_object_get_n_accessible_children(uList), ==, 3);
+
+ AtkObject* item1 = atk_object_ref_accessible_child(uList, 0);
+ g_assert(ATK_IS_TEXT(item1));
+ AtkObject* item2 = atk_object_ref_accessible_child(uList, 1);
+ g_assert(ATK_IS_TEXT(item2));
+ AtkObject* item3 = atk_object_ref_accessible_child(uList, 2);
+ g_assert(ATK_IS_TEXT(item3));
+
+ g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1);
+
+ g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item1), 0, -1), ==, "\342\200\242 text only");
+ g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item2), 0, -1), ==, "\342\200\242 link only");
+ g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item3), 0, -1), ==, "\342\200\242 text and a link");
+
+ g_object_unref(item1);
+ g_object_unref(item2);
+ g_object_unref(item3);
+
+ /* Ordered list. */
+
+ AtkObject* oList = atk_object_ref_accessible_child(object, 1);
+ g_assert(ATK_OBJECT(oList));
+ g_assert(atk_object_get_role(oList) == ATK_ROLE_LIST);
+ g_assert_cmpint(atk_object_get_n_accessible_children(oList), ==, 3);
+
+ item1 = atk_object_ref_accessible_child(oList, 0);
+ g_assert(ATK_IS_TEXT(item1));
+ item2 = atk_object_ref_accessible_child(oList, 1);
+ g_assert(ATK_IS_TEXT(item2));
+ item3 = atk_object_ref_accessible_child(oList, 2);
+ g_assert(ATK_IS_TEXT(item3));
+
+ g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item1), 0, -1), ==, "1. text only");
+ g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item2), 0, -1), ==, "2. link only");
+ g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item3), 0, -1), ==, "3. text and a link");
+
+ g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1);
+ g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1);
+
+ g_object_unref(item1);
+ g_object_unref(item2);
+ g_object_unref(item3);
+
+ g_object_unref(uList);
+ g_object_unref(oList);
+ g_object_unref(webView);
+}
+
+static gboolean textInserted = FALSE;
+static gboolean textDeleted = FALSE;
+
+static void textChangedCb(AtkText* text, gint pos, gint len, const gchar* detail)
+{
+ g_assert(text && ATK_IS_OBJECT(text));
+
+ if (!g_strcmp0(detail, "insert"))
+ textInserted = TRUE;
+ else if (!g_strcmp0(detail, "delete"))
+ textDeleted = TRUE;
+}
+
+static gboolean checkTextChanges(gpointer unused)
+{
+ g_assert_cmpint(textInserted, ==, TRUE);
+ g_assert_cmpint(textDeleted, ==, TRUE);
+ return FALSE;
+}
+
+static void testWebkitAtkTextChangedNotifications()
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ GtkAllocation allocation = { 0, 0, 800, 600 };
+ gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
+ webkit_web_view_load_string(webView, formWithTextInputs, 0, 0, 0);
+
+ /* Wait for the accessible objects to be created. */
+ waitForAccessibleObjects();
+
+ AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
+ g_assert(object);
+
+ AtkObject* form = atk_object_ref_accessible_child(object, 0);
+ g_assert(ATK_IS_OBJECT(form));
+
+ AtkObject* textEntry = atk_object_ref_accessible_child(form, 0);
+ g_assert(ATK_IS_EDITABLE_TEXT(textEntry));
+ g_assert(atk_object_get_role(ATK_OBJECT(textEntry)) == ATK_ROLE_ENTRY);
+
+ g_signal_connect(textEntry, "text-changed::insert",
+ G_CALLBACK(textChangedCb),
+ (gpointer)"insert");
+ g_signal_connect(textEntry, "text-changed::delete",
+ G_CALLBACK(textChangedCb),
+ (gpointer)"delete");
+
+ gint pos = 0;
+ atk_editable_text_insert_text(ATK_EDITABLE_TEXT(textEntry), "foo bar baz", 11, &pos);
+ atk_editable_text_delete_text(ATK_EDITABLE_TEXT(textEntry), 4, 7);
+ textInserted = FALSE;
+ textDeleted = FALSE;
+
+ g_idle_add((GSourceFunc)checkTextChanges, 0);
+
+ g_object_unref(form);
+ g_object_unref(textEntry);
+ g_object_unref(webView);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(0);
+ gtk_test_init(&argc, &argv, 0);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/atk/comboBox", testWebkitAtkComboBox);
+ g_test_add_func("/webkit/atk/getTextAtOffset", testWebkitAtkGetTextAtOffset);
+ g_test_add_func("/webkit/atk/getTextAtOffsetForms", testWebkitAtkGetTextAtOffsetForms);
+ g_test_add_func("/webkit/atk/getTextAtOffsetNewlines", testWebkitAtkGetTextAtOffsetNewlines);
+ g_test_add_func("/webkit/atk/getTextAtOffsetTextarea", testWebkitAtkGetTextAtOffsetTextarea);
+ g_test_add_func("/webkit/atk/getTextAtOffsetTextInput", testWebkitAtkGetTextAtOffsetTextInput);
+ g_test_add_func("/webkit/atk/getTextInParagraphAndBodySimple", testWebkitAtkGetTextInParagraphAndBodySimple);
+ g_test_add_func("/webkit/atk/getTextInParagraphAndBodyModerate", testWebkitAtkGetTextInParagraphAndBodyModerate);
+ g_test_add_func("/webkit/atk/getTextInTable", testWebkitAtkGetTextInTable);
+ g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable);
+ g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes);
+ g_test_add_func("/webkit/atk/textSelections", testWebkitAtkTextSelections);
+ g_test_add_func("/webkit/atk/getExtents", testWebkitAtkGetExtents);
+ g_test_add_func("/webkit/atk/hypertextAndHyperlinks", testWebkitAtkHypertextAndHyperlinks);
+ g_test_add_func("/webkit/atk/layoutAndDataTables", testWebkitAtkLayoutAndDataTables);
+ g_test_add_func("/webkit/atk/linksWithInlineImages", testWebkitAtkLinksWithInlineImages);
+ g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems);
+ g_test_add_func("/webkit/atk/textChangedNotifications", testWebkitAtkTextChangedNotifications);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testatkroles.c b/Source/WebKit/gtk/tests/testatkroles.c
new file mode 100644
index 0000000..5ad6b5f
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testatkroles.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright © 2010 Joanmarie Diggs
+ * Copyright © 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+/* Non form roles */
+#define HTML_DOCUMENT_FRAME "<html><body>This is a test.</body></html>"
+#define HTML_HEADING "<html><body><h1>1</h1><h2>2</h2><h3>3</h3><h4>4</h4><h5>5</h5><h6>6</h6></body></html>"
+#define HTML_IMAGE "<html><body><img src='foobar.png' alt='This is a test.'/></body></html>"
+#define HTML_LINK_TEXT "<html><body><a href='foobar.html'>This is a test.</a></body></html>"
+#define HTML_LIST "<html><body><ul><li>1</li><li>2</li></ul><ol><li>1</li><li>2</li></ol></body></html>"
+#define HTML_PARAGRAPH "<html><body><p>This is a test.</p></body></html>"
+#define HTML_SECTION "<html><body><div>This is a test.</div></body></html>"
+#define HTML_TABLE "<html><body><table border='1'><tr><td>This is</td><td>a test.</td></tr></table></body></html>"
+#define HTML_SEPARATOR "<html><body><hr/></body></html>"
+#define HTML_COMBOBOX "<html><body><select size='1'><option>one</option><option>two</option><option>three</option></select></body></html>"
+/* Form roles */
+#define HTML_FORM "<html><body><form>This is a test.</form></body></html>"
+#define HTML_CHECK_BOX "<html><body><input type='checkbox' />This is a test.</body></html>"
+#define HTML_LABELED_ENTRY "<html><body><label for='foo'>Name:</label><input type='text' id='foo' /></body></html>"
+#define HTML_LISTBOX "<html><body><select size='3'><option>one</option><option>two</option><option>three</option></select></body></html>"
+#define HTML_PASSWORD_TEXT "<html><body><input type='password' /></body></html>"
+#define HTML_PUSH_BUTTON "<html><body><input type='submit' value='ok' />This is a test.</body></html>"
+#define HTML_RADIO_BUTTON "<html><body><input type='radio' />This is a test.</body></html>"
+
+typedef struct {
+ AtkObject* documentFrame;
+ AtkObject* obj;
+ AtkRole role;
+ GtkWidget* webView;
+ GtkAllocation alloc;
+ GMainLoop* loop;
+} AtkRolesFixture;
+
+static gboolean finish_loading(AtkRolesFixture* fixture)
+{
+ if (g_main_loop_is_running(fixture->loop))
+ g_main_loop_quit(fixture->loop);
+
+ fixture->documentFrame = gtk_widget_get_accessible(fixture->webView);
+ g_assert(fixture->documentFrame);
+
+ return FALSE;
+}
+
+static void atk_roles_fixture_setup(AtkRolesFixture* fixture, gconstpointer data)
+{
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+ fixture->alloc = (GtkAllocation) { 0, 0, 800, 600 };
+ fixture->webView = webkit_web_view_new();
+ g_object_ref_sink(fixture->webView);
+
+ gtk_widget_size_allocate(fixture->webView, &fixture->alloc);
+
+ if (data != NULL)
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*) data, NULL, NULL, NULL);
+
+ g_idle_add((GSourceFunc) finish_loading, fixture);
+ g_main_loop_run(fixture->loop);
+}
+
+static void atk_roles_fixture_teardown(AtkRolesFixture* fixture, gconstpointer data)
+{
+ g_object_unref(fixture->webView);
+ g_main_loop_unref(fixture->loop);
+}
+
+static void get_child_and_test_role(AtkObject* obj, gint pos, AtkRole role)
+{
+ AtkObject* child;
+ AtkRole child_role;
+
+ child = atk_object_ref_accessible_child(obj, pos);
+ g_assert(child);
+ child_role = atk_object_get_role(child);
+ g_assert(child_role == role);
+
+ g_object_unref(child);
+}
+
+static void test_webkit_atk_get_role_document_frame(AtkRolesFixture* fixture, gconstpointer data)
+{
+ fixture->role = atk_object_get_role(fixture->documentFrame);
+ g_assert(fixture->role == ATK_ROLE_DOCUMENT_FRAME);
+}
+
+static void test_webkit_atk_get_role_heading(AtkRolesFixture* fixture, gconstpointer data)
+{
+ get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_HEADING);
+ get_child_and_test_role(fixture->documentFrame, 1, ATK_ROLE_HEADING);
+ get_child_and_test_role(fixture->documentFrame, 2, ATK_ROLE_HEADING);
+ get_child_and_test_role(fixture->documentFrame, 3, ATK_ROLE_HEADING);
+ get_child_and_test_role(fixture->documentFrame, 4, ATK_ROLE_HEADING);
+ get_child_and_test_role(fixture->documentFrame, 5, ATK_ROLE_HEADING);
+}
+
+static void test_webkit_atk_get_role_image(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_IMAGE);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_link(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_LINK);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_list_and_item(AtkRolesFixture* fixture, gconstpointer data)
+{
+ AtkObject* listObj;
+
+ listObj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(listObj);
+ fixture->role = atk_object_get_role(listObj);
+ g_assert(fixture->role == ATK_ROLE_LIST);
+
+ get_child_and_test_role(listObj, 0, ATK_ROLE_LIST_ITEM);
+ get_child_and_test_role(listObj, 1, ATK_ROLE_LIST_ITEM);
+ g_object_unref(listObj);
+
+ listObj = atk_object_ref_accessible_child(fixture->documentFrame, 1);
+ g_assert(listObj);
+ fixture->role = atk_object_get_role(listObj);
+ g_assert(fixture->role == ATK_ROLE_LIST);
+
+ get_child_and_test_role(listObj, 0, ATK_ROLE_LIST_ITEM);
+ get_child_and_test_role(listObj, 1, ATK_ROLE_LIST_ITEM);
+ g_object_unref(listObj);
+}
+
+static void test_webkit_atk_get_role_paragraph(AtkRolesFixture* fixture, gconstpointer data)
+{
+ get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_PARAGRAPH);
+}
+
+static void test_webkit_atk_get_role_section(AtkRolesFixture* fixture, gconstpointer data)
+{
+ get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_SECTION);
+}
+
+// Does not yet test table cells because of bug 30895.
+static void test_webkit_atk_get_role_table(AtkRolesFixture* fixture, gconstpointer data)
+{
+ get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_TABLE);
+}
+
+static void test_webkit_atk_get_role_separator(AtkRolesFixture *fixture, gconstpointer data)
+{
+ get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_SEPARATOR);
+}
+
+static void test_webkit_atk_get_role_combobox(AtkRolesFixture *fixture, gconstpointer data)
+{
+ AtkObject* comboboxMenu;
+
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ fixture->obj = atk_object_ref_accessible_child(fixture->obj, 0);
+ g_assert(fixture->obj);
+ fixture->role = atk_object_get_role(fixture->obj);
+ g_assert(fixture->role == ATK_ROLE_COMBO_BOX);
+
+ comboboxMenu = atk_object_ref_accessible_child(fixture->obj, 0);
+ g_assert(comboboxMenu);
+ fixture->role = atk_object_get_role(comboboxMenu);
+ g_assert(fixture->role == ATK_ROLE_MENU);
+
+ get_child_and_test_role(comboboxMenu, 0, ATK_ROLE_MENU_ITEM);
+ get_child_and_test_role(comboboxMenu, 1, ATK_ROLE_MENU_ITEM);
+ get_child_and_test_role(comboboxMenu, 2, ATK_ROLE_MENU_ITEM);
+
+ g_object_unref(fixture->obj);
+ g_object_unref(comboboxMenu);
+}
+
+/* Form roles */
+static void test_webkit_atk_get_role_form(AtkRolesFixture *fixture, gconstpointer data)
+{
+ get_child_and_test_role(fixture->documentFrame, 0, ATK_ROLE_FORM);
+}
+
+static void test_webkit_atk_get_role_check_box(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_CHECK_BOX);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_entry(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 1, ATK_ROLE_ENTRY);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_label(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_LABEL);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_listbox(AtkRolesFixture* fixture, gconstpointer data)
+{
+ AtkObject* listboxObj;
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ listboxObj = atk_object_ref_accessible_child(fixture->obj, 0);
+ g_assert(listboxObj);
+ fixture->role = atk_object_get_role(listboxObj);
+ g_assert(fixture->role == ATK_ROLE_LIST);
+
+ get_child_and_test_role(listboxObj, 0, ATK_ROLE_LIST_ITEM);
+ get_child_and_test_role(listboxObj, 1, ATK_ROLE_LIST_ITEM);
+ get_child_and_test_role(listboxObj, 2, ATK_ROLE_LIST_ITEM);
+
+ g_object_unref(fixture->obj);
+ g_object_unref(listboxObj);
+}
+
+static void test_webkit_atk_get_role_password_text(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_PASSWORD_TEXT);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_push_button(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_PUSH_BUTTON);
+
+ g_object_unref(fixture->obj);
+}
+
+static void test_webkit_atk_get_role_radio_button(AtkRolesFixture* fixture, gconstpointer data)
+{
+ // This is an extraneous object of ATK_ROLE_PANEL which we should get rid of.
+ fixture->obj = atk_object_ref_accessible_child(fixture->documentFrame, 0);
+ g_assert(fixture->obj);
+
+ get_child_and_test_role(fixture->obj, 0, ATK_ROLE_RADIO_BUTTON);
+
+ g_object_unref(fixture->obj);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_document_frame",
+ AtkRolesFixture, HTML_DOCUMENT_FRAME,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_document_frame,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_heading",
+ AtkRolesFixture, HTML_HEADING,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_heading,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_image",
+ AtkRolesFixture, HTML_IMAGE,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_image,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_link",
+ AtkRolesFixture, HTML_LINK_TEXT,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_link,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_list_and_item",
+ AtkRolesFixture, HTML_LIST,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_list_and_item,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_paragraph",
+ AtkRolesFixture, HTML_PARAGRAPH,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_paragraph,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_section",
+ AtkRolesFixture, HTML_SECTION,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_section,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_table",
+ AtkRolesFixture, HTML_TABLE,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_table,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_separator",
+ AtkRolesFixture, HTML_SEPARATOR,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_separator,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_combobox",
+ AtkRolesFixture, HTML_COMBOBOX,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_combobox,
+ atk_roles_fixture_teardown);
+
+ /* Form roles */
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_form",
+ AtkRolesFixture, HTML_FORM,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_form,
+ atk_roles_fixture_teardown);
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_check_box",
+ AtkRolesFixture, HTML_CHECK_BOX,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_check_box,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_entry",
+ AtkRolesFixture, HTML_LABELED_ENTRY,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_entry,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_label",
+ AtkRolesFixture, HTML_LABELED_ENTRY,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_label,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_listbox",
+ AtkRolesFixture, HTML_LISTBOX,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_listbox,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_password_text",
+ AtkRolesFixture, HTML_PASSWORD_TEXT,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_password_text,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_push_button",
+ AtkRolesFixture, HTML_PUSH_BUTTON,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_push_button,
+ atk_roles_fixture_teardown);
+
+ g_test_add("/webkit/atk/test_webkit_atk_get_role_radio_button",
+ AtkRolesFixture, HTML_RADIO_BUTTON,
+ atk_roles_fixture_setup,
+ test_webkit_atk_get_role_radio_button,
+ atk_roles_fixture_teardown);
+
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testcopyandpaste.c b/Source/WebKit/gtk/tests/testcopyandpaste.c
new file mode 100644
index 0000000..1b5fb7b
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testcopyandpaste.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <glib/gstdio.h>
+#include <webkit/webkit.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSContextRef.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+typedef struct {
+ char* page;
+ char* expectedContent;
+} TestInfo;
+
+typedef struct {
+ GtkWidget* window;
+ WebKitWebView* webView;
+ GMainLoop* loop;
+ TestInfo* info;
+} CopyAndPasteFixture;
+
+TestInfo*
+test_info_new(const char* page, const char* expectedContent)
+{
+ TestInfo* info;
+ info = g_slice_new0(TestInfo);
+ info->page = g_strdup(page);
+ if (expectedContent)
+ info->expectedContent = g_strdup(expectedContent);
+ return info;
+}
+
+void
+test_info_destroy(TestInfo* info)
+{
+ g_free(info->page);
+ g_free(info->expectedContent);
+ g_slice_free(TestInfo, info);
+}
+
+static void copy_and_paste_fixture_setup(CopyAndPasteFixture* fixture, gconstpointer data)
+{
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+
+ fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+
+ gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView));
+}
+
+static void copy_and_paste_fixture_teardown(CopyAndPasteFixture* fixture, gconstpointer data)
+{
+ gtk_widget_destroy(fixture->window);
+ g_main_loop_unref(fixture->loop);
+ test_info_destroy(fixture->info);
+}
+
+static void load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
+{
+ CopyAndPasteFixture* fixture = (CopyAndPasteFixture*)data;
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_clear(clipboard);
+
+ webkit_web_view_copy_clipboard(webView);
+
+ gchar* text = gtk_clipboard_wait_for_text(clipboard);
+ g_assert(text || !fixture->info->expectedContent);
+ g_assert(!text || !strcmp(text, fixture->info->expectedContent));
+ g_free(text);
+
+ // Verify that the markup starts with the proper content-type meta tag prefix.
+ GtkSelectionData* selectionData = gtk_clipboard_wait_for_contents(clipboard, gdk_atom_intern("text/html", FALSE));
+ if (selectionData) {
+ static const char* markupPrefix = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">";
+ char* markup = g_strndup((const char*) gtk_selection_data_get_data(selectionData),
+ gtk_selection_data_get_length(selectionData));
+ g_assert(strlen(markupPrefix) <= strlen(markup));
+ g_assert(!strncmp(markupPrefix, markup, strlen(markupPrefix)));
+ g_free(markup);
+ }
+
+ g_assert(!gtk_clipboard_wait_is_uris_available(clipboard));
+ g_assert(!gtk_clipboard_wait_is_image_available(clipboard));
+
+ g_main_loop_quit(fixture->loop);
+}
+
+gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data)
+{
+ gtk_widget_grab_focus(widget);
+ CopyAndPasteFixture* fixture = (CopyAndPasteFixture*)data;
+ webkit_web_view_load_string(fixture->webView, fixture->info->page,
+ "text/html", "utf-8", "file://");
+ return FALSE;
+}
+
+static void test_copy_and_paste(CopyAndPasteFixture* fixture, gconstpointer data)
+{
+ fixture->info = (TestInfo*)data;
+ g_signal_connect(fixture->window, "map-event",
+ G_CALLBACK(map_event_cb), fixture);
+
+ gtk_widget_show(fixture->window);
+ gtk_widget_show(GTK_WIDGET(fixture->webView));
+ gtk_window_present(GTK_WINDOW(fixture->window));
+
+ g_signal_connect(fixture->webView, "notify::load-status",
+ G_CALLBACK(load_status_cb), fixture);
+
+ g_main_loop_run(fixture->loop);
+}
+
+static CopyAndPasteFixture* currentFixture;
+static JSValueRef runPasteTestCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ // Simulate a paste keyboard sequence.
+ GdkEvent* event = gdk_event_new(GDK_KEY_PRESS);
+ event->key.keyval = gdk_unicode_to_keyval('v');
+ event->key.state = GDK_CONTROL_MASK;
+ event->key.window = gtk_widget_get_window(GTK_WIDGET(currentFixture->webView));
+ g_object_ref(event->key.window);
+#ifndef GTK_API_VERSION_2
+ GdkDeviceManager* manager = gdk_display_get_device_manager(gdk_window_get_display(event->key.window));
+ gdk_event_set_device(event, gdk_device_manager_get_client_pointer(manager));
+#endif
+
+ GdkKeymapKey* keys;
+ gint n_keys;
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), event->key.keyval, &keys, &n_keys)) {
+ event->key.hardware_keycode = keys[0].keycode;
+ g_free(keys);
+ }
+
+ gtk_main_do_event(event);
+ event->key.type = GDK_KEY_RELEASE;
+ gtk_main_do_event(event);
+ gdk_event_free(event);
+
+ JSStringRef scriptString = JSStringCreateWithUTF8CString("document.body.innerHTML;");
+ JSValueRef value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0);
+ JSStringRelease(scriptString);
+
+ g_assert(JSValueIsString(context, value));
+ JSStringRef actual = JSValueToStringCopy(context, value, exception);
+ g_assert(!exception || !*exception);
+ g_assert(currentFixture->info->expectedContent);
+ JSStringRef expected = JSStringCreateWithUTF8CString(currentFixture->info->expectedContent);
+ g_assert(JSStringIsEqual(expected, actual));
+
+ JSStringRelease(expected);
+ JSStringRelease(actual);
+ g_main_loop_quit(currentFixture->loop);
+ return JSValueMakeUndefined(context);
+}
+
+static void window_object_cleared_callback(WebKitWebView* web_view, WebKitWebFrame* web_frame, JSGlobalContextRef context, JSObjectRef window_object, gpointer data)
+{
+ JSStringRef name = JSStringCreateWithUTF8CString("runTest");
+ JSObjectRef testComplete = JSObjectMakeFunctionWithCallback(context, name, runPasteTestCallback);
+ JSObjectSetProperty(context, window_object, name, testComplete, kJSPropertyAttributeNone, 0);
+ JSStringRelease(name);
+}
+
+static void pasting_test_get_data_callback(GtkClipboard* clipboard, GtkSelectionData* selection_data, guint info, gpointer data)
+{
+ gtk_selection_data_set(selection_data, gdk_atom_intern("text/html", FALSE), 8, (const guchar*) data, strlen((char*)data) + 1);
+}
+
+static void pasting_test_clear_data_callback(GtkClipboard* clipboard, gpointer data)
+{
+ g_free(data);
+}
+
+static void test_pasting_markup(CopyAndPasteFixture* fixture, gconstpointer data)
+{
+ fixture->info = (TestInfo*)data;
+ currentFixture = fixture;
+
+ GtkTargetList* targetList = gtk_target_list_new(0, 0);
+ gtk_target_list_add(targetList, gdk_atom_intern("text/html", FALSE), 0, 0);
+
+ int numberOfTargets = 1;
+ GtkTargetEntry* targetTable = gtk_target_table_new_from_list(targetList, &numberOfTargets);
+ gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
+ targetTable, numberOfTargets,
+ pasting_test_get_data_callback,
+ pasting_test_clear_data_callback,
+ g_strdup(fixture->info->expectedContent));
+ gtk_target_list_unref(targetList);
+ gtk_target_table_free(targetTable, numberOfTargets);
+
+ g_signal_connect(fixture->window, "map-event",
+ G_CALLBACK(map_event_cb), fixture);
+ g_signal_connect(fixture->webView, "window-object-cleared",
+ G_CALLBACK(window_object_cleared_callback), fixture);
+
+ gtk_widget_show(fixture->window);
+ gtk_widget_show(GTK_WIDGET(fixture->webView));
+ gtk_window_present(GTK_WINDOW(fixture->window));
+
+ g_main_loop_run(fixture->loop);
+}
+
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ const char* selected_span_html = "<html><body>"
+ "<span id=\"mainspan\">All work and no play <span>make Jack a dull</span> boy.</span>"
+ "<script>document.getSelection().collapse();\n"
+ "document.getSelection().selectAllChildren(document.getElementById('mainspan'));\n"
+ "</script></body></html>";
+ const char* no_selection_html = "<html><body>"
+ "<span id=\"mainspan\">All work and no play <span>make Jack a dull</span> boy</span>"
+ "<script>document.getSelection().collapse();\n"
+ "</script></body></html>";
+
+ g_test_add("/webkit/copyandpaste/selection", CopyAndPasteFixture,
+ test_info_new(selected_span_html, "All work and no play make Jack a dull boy."),
+ copy_and_paste_fixture_setup,
+ test_copy_and_paste,
+ copy_and_paste_fixture_teardown);
+ g_test_add("/webkit/copyandpaste/no-selection", CopyAndPasteFixture,
+ test_info_new(no_selection_html, 0),
+ copy_and_paste_fixture_setup,
+ test_copy_and_paste,
+ copy_and_paste_fixture_teardown);
+
+ const char* paste_test_html = "<html>"
+ "<body onLoad=\"document.body.focus(); runTest();\" contentEditable=\"true\">"
+ "</body></html>";
+ g_test_add("/webkit/copyandpaste/paste-markup", CopyAndPasteFixture,
+ test_info_new(paste_test_html, "bobby"),
+ copy_and_paste_fixture_setup,
+ test_pasting_markup,
+ copy_and_paste_fixture_teardown);
+
+ return g_test_run();
+}
+
+#else
+
+int main(int argc, char** argv)
+{
+ g_critical("You will need at least GTK+ 2.14.0 to run the unit tests.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testdomdocument.c b/Source/WebKit/gtk/tests/testdomdocument.c
new file mode 100644
index 0000000..aa6cbb3
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testdomdocument.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "test_utils.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+#define HTML_DOCUMENT_TITLE "<html><head><title>This is the title</title></head><body></body></html>"
+#define HTML_DOCUMENT_ELEMENTS "<html><body><ul><li>1</li><li>2</li><li>3</li></ul></body></html>"
+#define HTML_DOCUMENT_ELEMENTS_CLASS "<html><body><div class=\"test\"></div><div class=\"strange\"></div><div class=\"test\"></div></body></html>"
+#define HTML_DOCUMENT_ELEMENTS_ID "<html><body><div id=\"testok\"></div><div id=\"testbad\">first</div><div id=\"testbad\">second</div></body></html>"
+#define HTML_DOCUMENT_LINKS "<html><head><title>Title</title></head><body><a href=\"about:blank\">blank</a><a href=\"http://www.google.com\">google</a><a href=\"http://www.webkit.org\">webkit</a></body></html>"
+#define HTML_DOCUMENT_IFRAME "<html><head><title>IFrame</title></head><body><iframe id='iframe'></iframe><div id='test'></div></body></html>"
+
+typedef struct {
+ GtkWidget* webView;
+ GMainLoop* loop;
+} DomDocumentFixture;
+
+static gboolean finish_loading(DomDocumentFixture* fixture)
+{
+ if (g_main_loop_is_running(fixture->loop))
+ g_main_loop_quit(fixture->loop);
+
+ return FALSE;
+}
+
+static void dom_document_fixture_setup(DomDocumentFixture* fixture, gconstpointer data)
+{
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+ fixture->webView = webkit_web_view_new();
+ g_object_ref_sink(fixture->webView);
+
+ if (data != NULL)
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*) data, NULL, NULL, NULL);
+
+ g_idle_add((GSourceFunc)finish_loading, fixture);
+ g_main_loop_run(fixture->loop);
+}
+
+static void dom_document_fixture_teardown(DomDocumentFixture* fixture, gconstpointer data)
+{
+ if (fixture->webView)
+ g_object_unref(fixture->webView);
+ g_main_loop_unref(fixture->loop);
+}
+
+static void test_dom_document_title(DomDocumentFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ gchar* title = webkit_dom_document_get_title(document);
+ g_assert(title);
+ g_assert_cmpstr(title, ==, "This is the title");
+ g_free(title);
+ webkit_dom_document_set_title(document, "This is the second title");
+ title = webkit_dom_document_get_title(document);
+ g_assert(title);
+ g_assert_cmpstr(title, ==, "This is the second title");
+ g_free(title);
+}
+
+static void test_dom_document_get_elements_by_tag_name(DomDocumentFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_tag_name(document, "li");
+ g_assert(list);
+ gulong length = webkit_dom_node_list_get_length(list);
+ g_assert_cmpint(length, ==, 3);
+
+ guint i;
+
+ for (i = 0; i < length; i++) {
+ WebKitDOMNode* item = webkit_dom_node_list_item(list, i);
+ g_assert(item);
+ WebKitDOMElement* element = (WebKitDOMElement*)item;
+ g_assert(element);
+ g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "LI");
+ WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element;
+ char* n = g_strdup_printf("%d", i+1);
+ g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, n);
+ g_free(n);
+ }
+
+ g_object_unref(list);
+}
+
+static void test_dom_document_get_elements_by_class_name(DomDocumentFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_class_name(document, "test");
+ g_assert(list);
+ gulong length = webkit_dom_node_list_get_length(list);
+ g_assert_cmpint(length, ==, 2);
+
+ guint i;
+
+ for (i = 0; i < length; i++) {
+ WebKitDOMNode* item = webkit_dom_node_list_item(list, i);
+ g_assert(item);
+ WebKitDOMElement* element = (WebKitDOMElement*)item;
+ g_assert(element);
+ g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "DIV");
+ }
+
+ g_object_unref(list);
+}
+
+static void test_dom_document_get_element_by_id(DomDocumentFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ WebKitDOMElement* element = webkit_dom_document_get_element_by_id(document, "testok");
+ g_assert(element);
+ element = webkit_dom_document_get_element_by_id(document, "this-id-does-not-exist");
+ g_assert(element == 0);
+ /* The DOM spec says the return value is undefined when there's
+ * more than one element with the same id; in our case the first
+ * one will be returned */
+ element = webkit_dom_document_get_element_by_id(document, "testbad");
+ g_assert(element);
+ WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element;
+ g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, "first");
+}
+
+static void test_dom_document_get_links(DomDocumentFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ WebKitDOMHTMLCollection *collection = webkit_dom_document_get_links(document);
+ g_assert(collection);
+ gulong length = webkit_dom_html_collection_get_length(collection);
+ g_assert_cmpint(length, ==, 3);
+
+ guint i;
+
+ for (i = 0; i < length; i++) {
+ static const char* names[] = { "blank", "google", "webkit" };
+ static const char* uris[] = { "about:blank", "http://www.google.com/", "http://www.webkit.org/" };
+ WebKitDOMNode *node = webkit_dom_html_collection_item(collection, i);
+ g_assert(node);
+ WebKitDOMElement* element = (WebKitDOMElement*)node;
+ g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "A");
+ WebKitDOMHTMLElement *htmlElement = (WebKitDOMHTMLElement*)element;
+ g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, names[i]);
+ WebKitDOMHTMLAnchorElement *anchor = (WebKitDOMHTMLAnchorElement*)element;
+ g_assert_cmpstr(webkit_dom_html_anchor_element_get_href(anchor), ==, uris[i]);
+ }
+ g_object_unref(collection);
+}
+
+static void weak_notify(gpointer data, GObject* zombie)
+{
+ guint* count = (guint*)data;
+ (*count)++;
+}
+
+static void test_dom_document_garbage_collection(DomDocumentFixture* fixture, gconstpointer data)
+{
+ guint count = 0;
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count);
+ WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document);
+ g_assert(head);
+ g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count);
+ WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document);
+ g_assert(body);
+ g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count);
+ WebKitDOMHTMLCollection *collection = webkit_dom_document_get_links(document);
+ g_assert(collection);
+ g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count);
+
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_LINKS, NULL, NULL, NULL);
+
+ while (g_main_context_pending(NULL))
+ g_main_context_iteration(NULL, FALSE);
+
+ g_assert_cmpuint(count, ==, 3);
+
+ g_object_unref(collection);
+ g_assert_cmpuint(count, ==, 4);
+
+ count = 0;
+
+ document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count);
+ head = webkit_dom_document_get_head(document);
+ g_assert(head);
+ g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count);
+ body = webkit_dom_document_get_body(document);
+ g_assert(body);
+ g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count);
+ collection = webkit_dom_document_get_links(document);
+ g_assert(collection);
+ g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count);
+ /* Ask twice for the same object */
+ WebKitDOMHTMLCollection* collection2 = webkit_dom_document_get_links(document);
+ g_assert(collection2);
+ g_object_weak_ref(G_OBJECT(collection2), (GWeakNotify)weak_notify, &count);
+
+ g_object_unref(document);
+ g_object_unref(head);
+ g_object_unref(body);
+ g_object_unref(collection);
+ g_object_unref(collection2);
+
+ g_assert_cmpuint(count, ==, 5);
+
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_IFRAME, NULL, NULL, NULL);
+
+ while (g_main_context_pending(NULL))
+ g_main_context_iteration(NULL, FALSE);
+
+ count = 0;
+
+ document = webkit_web_view_get_dom_document(view);
+ WebKitDOMElement* div = webkit_dom_document_get_element_by_id(document, "test");
+ g_assert(div);
+ g_object_weak_ref(G_OBJECT(div), (GWeakNotify)weak_notify, &count);
+ WebKitDOMElement* iframe = webkit_dom_document_get_element_by_id(document, "iframe");
+ g_assert(iframe);
+
+ webkit_dom_element_set_attribute(iframe, "src", "data:<html><head></head></html>", NULL);
+
+ while (g_main_context_pending(NULL))
+ g_main_context_iteration(NULL, FALSE);
+
+ WebKitDOMDocument* iframeDocument = webkit_dom_html_iframe_element_get_content_document(WEBKIT_DOM_HTML_IFRAME_ELEMENT(iframe));
+ g_assert(iframeDocument);
+ head = webkit_dom_document_get_head(iframeDocument);
+ g_assert(head);
+ g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count);
+
+ webkit_dom_element_set_attribute(iframe, "src", "about:blank", NULL);
+
+ while (g_main_context_pending(NULL))
+ g_main_context_iteration(NULL, FALSE);
+
+ g_assert_cmpuint(count, ==, 1);
+
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_LINKS, NULL, NULL, NULL);
+
+ while (g_main_context_pending(NULL))
+ g_main_context_iteration(NULL, FALSE);
+
+ g_assert_cmpuint(count, ==, 2);
+
+ count = 0;
+
+ document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count);
+ /* Ask twice for the Document */
+ WebKitDOMDocument* document2 = webkit_web_view_get_dom_document(view);
+ g_assert(document2);
+ g_object_weak_ref(G_OBJECT(document2), (GWeakNotify)weak_notify, &count);
+ head = webkit_dom_document_get_head(document);
+ g_assert(head);
+ g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count);
+ body = webkit_dom_document_get_body(document);
+ g_assert(body);
+ g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count);
+ collection = webkit_dom_document_get_links(document);
+ g_assert(collection);
+ g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count);
+
+ gtk_widget_destroy(fixture->webView);
+ fixture->webView = NULL;
+
+ g_assert_cmpuint(count, ==, 4);
+
+ g_object_unref(collection);
+
+ g_assert_cmpuint(count, ==, 5);
+}
+
+int main(int argc, char** argv)
+{
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+
+ g_test_add("/webkit/domdocument/test_title",
+ DomDocumentFixture, HTML_DOCUMENT_TITLE,
+ dom_document_fixture_setup,
+ test_dom_document_title,
+ dom_document_fixture_teardown);
+
+ g_test_add("/webkit/domdocument/test_get_elements_by_tag_name",
+ DomDocumentFixture, HTML_DOCUMENT_ELEMENTS,
+ dom_document_fixture_setup,
+ test_dom_document_get_elements_by_tag_name,
+ dom_document_fixture_teardown);
+
+ g_test_add("/webkit/domdocument/test_get_elements_by_class_name",
+ DomDocumentFixture, HTML_DOCUMENT_ELEMENTS_CLASS,
+ dom_document_fixture_setup,
+ test_dom_document_get_elements_by_class_name,
+ dom_document_fixture_teardown);
+
+ g_test_add("/webkit/domdocument/test_get_element_by_id",
+ DomDocumentFixture, HTML_DOCUMENT_ELEMENTS_ID,
+ dom_document_fixture_setup,
+ test_dom_document_get_element_by_id,
+ dom_document_fixture_teardown);
+
+ g_test_add("/webkit/domdocument/test_get_links",
+ DomDocumentFixture, HTML_DOCUMENT_LINKS,
+ dom_document_fixture_setup,
+ test_dom_document_get_links,
+ dom_document_fixture_teardown);
+
+ g_test_add("/webkit/domdocument/test_garbage_collection",
+ DomDocumentFixture, HTML_DOCUMENT_LINKS,
+ dom_document_fixture_setup,
+ test_dom_document_garbage_collection,
+ dom_document_fixture_teardown);
+
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testdomdomwindow.c b/Source/WebKit/gtk/tests/testdomdomwindow.c
new file mode 100644
index 0000000..b15558e
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testdomdomwindow.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "test_utils.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+#define HTML_DOCUMENT "<html><head><title>This is the title</title></head><body><p id='test'>test</p></body></html>"
+
+typedef struct {
+ GtkWidget* webView;
+ GtkWidget* window;
+ WebKitDOMDOMWindow* domWindow;
+ GMainLoop* loop;
+
+ gboolean loaded;
+ gboolean clicked;
+ gconstpointer data;
+} DomDomviewFixture;
+
+static gboolean finish_loading(DomDomviewFixture* fixture)
+{
+ if (g_main_loop_is_running(fixture->loop))
+ g_main_loop_quit(fixture->loop);
+
+ return FALSE;
+}
+
+static void dom_domview_fixture_setup(DomDomviewFixture* fixture, gconstpointer data)
+{
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+ fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ fixture->webView = webkit_web_view_new();
+ fixture->data = data;
+
+ gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView));
+}
+
+static void dom_domview_fixture_teardown(DomDomviewFixture* fixture, gconstpointer data)
+{
+ gtk_widget_destroy(fixture->window);
+ g_main_loop_unref(fixture->loop);
+}
+
+static gboolean loadedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, DomDomviewFixture* fixture)
+{
+ g_assert(fixture->loaded == FALSE);
+ fixture->loaded = TRUE;
+
+ return FALSE;
+}
+
+static gboolean clickedCallback(WebKitDOMDOMWindow* view, WebKitDOMEvent* event, DomDomviewFixture* fixture)
+{
+ WebKitDOMEventTarget* target;
+ gushort phase;
+
+ g_assert(event);
+ g_assert(WEBKIT_DOM_IS_EVENT(event));
+
+ // We should catch this in the bubbling up phase, since we are connecting to the toplevel object
+ phase = webkit_dom_event_get_event_phase(event);
+ g_assert_cmpint(phase, ==, 3);
+
+ target = webkit_dom_event_get_current_target(event);
+ g_assert(target == WEBKIT_DOM_EVENT_TARGET(view));
+
+ g_assert(fixture->clicked == FALSE);
+ fixture->clicked = TRUE;
+
+ finish_loading(fixture);
+
+ return FALSE;
+}
+
+gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, DomDomviewFixture* fixture)
+{
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*)fixture->data, NULL, NULL, NULL);
+
+ return FALSE;
+}
+
+static void load_event_callback(WebKitWebView* webView, GParamSpec* spec, DomDomviewFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status == WEBKIT_LOAD_FINISHED) {
+ g_signal_connect(fixture->domWindow, "click-event", G_CALLBACK(clickedCallback), fixture);
+
+ g_assert(fixture->clicked == FALSE);
+ gtk_test_widget_click(GTK_WIDGET(fixture->webView), 1, 0);
+ }
+
+}
+
+static void test_dom_domview_signals(DomDomviewFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture);
+ WebKitWebView* view = (WebKitWebView*)fixture->webView;
+ g_assert(view);
+ WebKitDOMDocument* document = webkit_web_view_get_dom_document(view);
+ g_assert(document);
+ WebKitDOMDOMWindow* domWindow = webkit_dom_document_get_default_view(document);
+ g_assert(domWindow);
+
+ fixture->domWindow = domWindow;
+
+ g_signal_connect(fixture->domWindow, "load-event", G_CALLBACK(loadedCallback), fixture);
+ g_signal_connect(fixture->window, "map-event", G_CALLBACK(map_event_cb), fixture);
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_event_callback), fixture);
+
+ gtk_widget_show_all(fixture->window);
+ gtk_window_present(GTK_WINDOW(fixture->window));
+
+ g_main_loop_run(fixture->loop);
+
+ g_assert(fixture->loaded);
+ g_assert(fixture->clicked);
+}
+
+static gboolean
+clicked_cb(WebKitDOMEventTarget* target, WebKitDOMEvent* event, DomDomviewFixture* fixture)
+{
+ g_assert(fixture->clicked == FALSE);
+ fixture->clicked = TRUE;
+ finish_loading(fixture);
+ return FALSE;
+}
+
+static void load_status_callback(WebKitWebView* webView, GParamSpec* spec, DomDomviewFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status == WEBKIT_LOAD_FINISHED) {
+ WebKitDOMDocument* document;
+ WebKitDOMDOMWindow* domWindow;
+ WebKitDOMElement* element;
+ WebKitDOMEvent* event;
+ glong clientX, clientY;
+
+ document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView));
+ g_assert(document);
+ domWindow = webkit_dom_document_get_default_view(document);
+ g_assert(domWindow);
+ fixture->domWindow = domWindow;
+
+ element = webkit_dom_document_get_element_by_id(document, "test");
+ g_assert(element);
+ event = webkit_dom_document_create_event(document, "MouseEvent", NULL);
+ g_assert(event);
+ g_assert(WEBKIT_DOM_IS_EVENT(event));
+ g_assert(WEBKIT_DOM_IS_MOUSE_EVENT(event));
+ clientX = webkit_dom_element_get_client_left(element);
+ clientY = webkit_dom_element_get_client_top(element);
+ webkit_dom_mouse_event_init_mouse_event(WEBKIT_DOM_MOUSE_EVENT(event),
+ "click", TRUE, TRUE,
+ fixture->domWindow, 0, 0, 0, clientX, clientY,
+ FALSE, FALSE, FALSE, FALSE,
+ 1, WEBKIT_DOM_EVENT_TARGET(element));
+ g_signal_connect(element, "click-event", G_CALLBACK(clicked_cb), fixture);
+ g_assert(fixture->clicked == FALSE);
+ webkit_dom_event_target_dispatch_event(WEBKIT_DOM_EVENT_TARGET(element), event, NULL);
+ }
+
+}
+
+static void test_dom_domview_dispatch_event(DomDomviewFixture* fixture, gconstpointer data)
+{
+ g_signal_connect(fixture->window, "map-event", G_CALLBACK(map_event_cb), fixture);
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_status_callback), fixture);
+
+ gtk_widget_show_all(fixture->window);
+ gtk_window_present(GTK_WINDOW(fixture->window));
+
+ g_main_loop_run (fixture->loop);
+ g_assert(fixture->clicked);
+}
+
+int main(int argc, char** argv)
+{
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+
+ g_test_add("/webkit/domdomview/signals",
+ DomDomviewFixture, HTML_DOCUMENT,
+ dom_domview_fixture_setup,
+ test_dom_domview_signals,
+ dom_domview_fixture_teardown);
+
+ g_test_add("/webkit/domdomview/dispatch_event",
+ DomDomviewFixture, HTML_DOCUMENT,
+ dom_domview_fixture_setup,
+ test_dom_domview_dispatch_event,
+ dom_domview_fixture_teardown);
+
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testdomnode.c b/Source/WebKit/gtk/tests/testdomnode.c
new file mode 100644
index 0000000..893b7cc
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testdomnode.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "test_utils.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+#define HTML_DOCUMENT_HIERARCHY_NAVIGATION "<html><head><title>This is the title</title></head><body><p>1</p><p>2</p><p>3</p></body></html>"
+#define HTML_DOCUMENT_NODE_INSERTION "<html><body></body></html>"
+
+typedef struct {
+ GtkWidget* webView;
+ GMainLoop* loop;
+} DomNodeFixture;
+
+static gboolean finish_loading(DomNodeFixture* fixture)
+{
+ if (g_main_loop_is_running(fixture->loop))
+ g_main_loop_quit(fixture->loop);
+
+ return FALSE;
+}
+
+static void dom_node_fixture_setup(DomNodeFixture* fixture, gconstpointer data)
+{
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+ fixture->webView = webkit_web_view_new();
+ g_object_ref_sink(fixture->webView);
+
+ if (data != NULL)
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(fixture->webView), (const char*)data, NULL, NULL, NULL);
+
+ g_idle_add((GSourceFunc)finish_loading, fixture);
+ g_main_loop_run(fixture->loop);
+}
+
+static void dom_node_fixture_teardown(DomNodeFixture* fixture, gconstpointer data)
+{
+ g_object_unref(fixture->webView);
+ g_main_loop_unref(fixture->loop);
+}
+
+static void test_dom_node_hierarchy_navigation(DomNodeFixture* fixture, gconstpointer data)
+{
+ WebKitDOMDocument* document;
+ WebKitDOMHTMLHeadElement* head;
+ WebKitDOMHTMLBodyElement* body;
+ WebKitDOMNodeList* list;
+ WebKitDOMNode* ptr;
+ gulong i, length;
+
+ document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView));
+ g_assert(document);
+ g_assert(WEBKIT_DOM_IS_DOCUMENT(document));
+ head = webkit_dom_document_get_head(document);
+ g_assert(head);
+ g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(head));
+
+ /* Title, head's child */
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(head)));
+ list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(head));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1);
+ ptr = webkit_dom_node_list_item(list, 0);
+ g_assert(ptr);
+ g_assert(WEBKIT_DOM_IS_HTML_TITLE_ELEMENT(ptr));
+ g_object_unref(list);
+
+ /* Body, Head sibling */
+ ptr = webkit_dom_node_get_next_sibling(WEBKIT_DOM_NODE(head));
+ g_assert(ptr);
+ body = WEBKIT_DOM_HTML_BODY_ELEMENT(ptr);
+ g_assert(WEBKIT_DOM_IS_HTML_BODY_ELEMENT(body));
+
+ /* There is no third sibling */
+ ptr = webkit_dom_node_get_next_sibling(ptr);
+ g_assert(ptr == NULL);
+
+ /* Body's previous sibling is Head */
+ ptr = webkit_dom_node_get_previous_sibling(WEBKIT_DOM_NODE(body));
+ g_assert(ptr);
+ g_assert(WEBKIT_DOM_IS_HTML_HEAD_ELEMENT(ptr));
+
+ /* Body has 3 children */
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body));
+ length = webkit_dom_node_list_get_length(list);
+ g_assert_cmpint(length, ==, 3);
+
+ /* The three of them are P tags */
+ for (i = 0; i < length; i++) {
+ ptr = webkit_dom_node_list_item(list, i);
+ g_assert(ptr);
+ g_assert(WEBKIT_DOM_IS_HTML_PARAGRAPH_ELEMENT(ptr));
+ }
+
+ /* Go backwards */
+ for (i = 0; ptr; ptr = webkit_dom_node_get_previous_sibling(ptr), i++)
+ /* Nothing */;
+
+ g_assert_cmpint(i, ==, 3);
+ g_object_unref(list);
+}
+
+static void test_dom_node_insertion(DomNodeFixture* fixture, gconstpointer data)
+{
+ WebKitDOMDocument* document;
+ WebKitDOMHTMLElement* body;
+ WebKitDOMElement* p, *div;
+ WebKitDOMNodeList* list;
+ WebKitDOMNode* node;
+
+ document = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(fixture->webView));
+ g_assert(document);
+ body = webkit_dom_document_get_body(document);
+ g_assert(body);
+ g_assert(WEBKIT_DOM_IS_HTML_ELEMENT(body));
+
+ /* Body shouldn't have any children at this point */
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)) == FALSE);
+
+ /* Insert one P element */
+ p = webkit_dom_document_create_element(document, "P", NULL);
+ webkit_dom_node_append_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(p), NULL);
+
+ /* Now it should have one, the same that we inserted */
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1);
+ node = webkit_dom_node_list_item(list, 0);
+ g_assert(node);
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(p), node));
+ g_object_unref(list);
+
+ /* Replace the P tag with a DIV tag */
+ div = webkit_dom_document_create_element(document, "DIV", NULL);
+ webkit_dom_node_replace_child(WEBKIT_DOM_NODE(body), WEBKIT_DOM_NODE(div), WEBKIT_DOM_NODE(p), NULL);
+ g_assert(webkit_dom_node_has_child_nodes(WEBKIT_DOM_NODE(body)));
+ list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 1);
+ node = webkit_dom_node_list_item(list, 0);
+ g_assert(node);
+ g_assert(webkit_dom_node_is_same_node(WEBKIT_DOM_NODE(div), node));
+ g_object_unref(list);
+
+ /* Now remove the tag */
+ webkit_dom_node_remove_child(WEBKIT_DOM_NODE(body), node, NULL);
+ list = webkit_dom_node_get_child_nodes(WEBKIT_DOM_NODE(body));
+ g_assert_cmpint(webkit_dom_node_list_get_length(list), ==, 0);
+ g_object_unref(list);
+
+ /* TODO: insert_before, which does not seem to be working correctly */
+}
+
+int main(int argc, char** argv)
+{
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+
+ g_test_add("/webkit/domnode/test_hierarchy_navigation",
+ DomNodeFixture, HTML_DOCUMENT_HIERARCHY_NAVIGATION,
+ dom_node_fixture_setup,
+ test_dom_node_hierarchy_navigation,
+ dom_node_fixture_teardown);
+
+ g_test_add("/webkit/domnode/test_insertion",
+ DomNodeFixture, HTML_DOCUMENT_NODE_INSERTION,
+ dom_node_fixture_setup,
+ test_dom_node_insertion,
+ dom_node_fixture_teardown);
+
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testdownload.c b/Source/WebKit/gtk/tests/testdownload.c
new file mode 100644
index 0000000..f6ae865
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testdownload.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <glib/gstdio.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+GMainLoop* loop;
+char* temporaryFilename = NULL;
+WebKitDownload* theDownload = NULL;
+
+static void
+test_webkit_download_create(void)
+{
+ WebKitNetworkRequest* request;
+ WebKitDownload* download;
+ const gchar* uri = "http://example.com";
+ gchar* tmpDir;
+
+ request = webkit_network_request_new(uri);
+ download = webkit_download_new(request);
+ g_object_unref(request);
+ g_assert_cmpstr(webkit_download_get_uri(download), ==, uri);
+ g_assert(webkit_download_get_network_request(download) == request);
+ g_assert(g_strrstr(uri, webkit_download_get_suggested_filename(download)));
+ g_assert(webkit_download_get_status(download) == WEBKIT_DOWNLOAD_STATUS_CREATED);
+ g_assert(!webkit_download_get_total_size(download));
+ g_assert(!webkit_download_get_current_size(download));
+ g_assert(!webkit_download_get_progress(download));
+ g_assert(!webkit_download_get_elapsed_time(download));
+ tmpDir = g_filename_to_uri(g_get_tmp_dir(), NULL, NULL);
+ webkit_download_set_destination_uri(download, tmpDir);
+ g_assert_cmpstr(tmpDir, ==, webkit_download_get_destination_uri(download));;
+ g_free(tmpDir);
+ g_object_unref(download);
+}
+
+static gboolean
+navigation_policy_decision_requested_cb(WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ WebKitNetworkRequest* request,
+ WebKitWebNavigationAction* action,
+ WebKitWebPolicyDecision* decision,
+ gpointer data)
+{
+ webkit_web_policy_decision_download(decision);
+ return TRUE;
+}
+
+static void
+notify_status_cb(GObject* object, GParamSpec* pspec, gpointer data)
+{
+ WebKitDownload* download = WEBKIT_DOWNLOAD(object);
+ switch (webkit_download_get_status(download)) {
+ case WEBKIT_DOWNLOAD_STATUS_FINISHED:
+ case WEBKIT_DOWNLOAD_STATUS_ERROR:
+ g_main_loop_quit(loop);
+ break;
+ case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
+ g_assert_not_reached();
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+set_filename(gchar* filename)
+{
+ gchar *uri = g_filename_to_uri(filename, NULL, NULL);
+
+ webkit_download_set_destination_uri(theDownload, uri);
+ g_free(uri);
+
+ webkit_download_start(theDownload);
+ return FALSE;
+}
+
+static void
+handle_download_requested_cb(WebKitDownload* download,
+ gboolean* beenThere,
+ gboolean asynch)
+{
+ theDownload = download;
+ *beenThere = TRUE;
+
+ if (temporaryFilename) {
+ if (asynch) {
+ g_idle_add((GSourceFunc)set_filename, temporaryFilename);
+ } else {
+ gchar *uri = g_filename_to_uri(temporaryFilename, NULL, NULL);
+ if (uri)
+ webkit_download_set_destination_uri(download, uri);
+ g_free(uri);
+ }
+ }
+
+ g_signal_connect(download, "notify::status",
+ G_CALLBACK(notify_status_cb), NULL);
+}
+
+static gboolean
+download_requested_cb(WebKitWebView* web_view,
+ WebKitDownload* download,
+ gboolean* beenThere)
+{
+ handle_download_requested_cb(download, beenThere, FALSE);
+ return TRUE;
+}
+
+static gboolean
+download_requested_asynch_cb(WebKitWebView* web_view,
+ WebKitDownload* download,
+ gboolean* beenThere)
+{
+ handle_download_requested_cb(download, beenThere, TRUE);
+ return TRUE;
+}
+
+static void
+test_webkit_download_perform(gboolean asynch)
+{
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ GCallback downloadRequestCallback = NULL;
+
+ g_object_ref_sink(G_OBJECT(webView));
+
+ g_signal_connect(webView, "navigation-policy-decision-requested",
+ G_CALLBACK(navigation_policy_decision_requested_cb),
+ NULL);
+
+ if (asynch)
+ downloadRequestCallback = G_CALLBACK(download_requested_asynch_cb);
+ else
+ downloadRequestCallback = G_CALLBACK(download_requested_cb);
+
+ gboolean beenThere = FALSE;
+ g_signal_connect(webView, "download-requested",
+ downloadRequestCallback, &beenThere);
+
+ /* Preparation; FIXME: we should move this code to a test
+ * utilities file, because we have a very similar one in
+ * testwebframe.c */
+ GError *error = NULL;
+ gchar* filename;
+ int fd = g_file_open_tmp("webkit-testwebdownload-XXXXXX", &filename, &error);
+ close(fd);
+
+ if (error)
+ g_critical("Failed to open a temporary file for writing: %s.", error->message);
+
+ if (g_unlink(filename) == -1)
+ g_critical("Failed to delete the temporary file: %s.", g_strerror(errno));
+
+ theDownload = NULL;
+ temporaryFilename = filename;
+
+ loop = g_main_loop_new(NULL, TRUE);
+ webkit_web_view_load_uri(webView, "http://gnome.org/");
+ g_main_loop_run(loop);
+
+ g_assert_cmpint(beenThere, ==, TRUE);
+
+ g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE);
+
+ g_unlink(temporaryFilename);
+ g_free(temporaryFilename);
+ temporaryFilename = NULL;
+
+ g_main_loop_unref(loop);
+ g_object_unref(webView);
+}
+
+static void
+test_webkit_download_synch(void)
+{
+ test_webkit_download_perform(FALSE);
+}
+
+static void
+test_webkit_download_asynch(void)
+{
+ test_webkit_download_perform(TRUE);
+}
+
+static gboolean mime_type_policy_decision_requested_cb(WebKitWebView* view, WebKitWebFrame* frame,
+ WebKitNetworkRequest* request, const char* mime_type,
+ WebKitWebPolicyDecision* decision, gpointer data)
+{
+ webkit_web_policy_decision_download(decision);
+ return TRUE;
+}
+
+static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED ||
+ webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED)
+ g_main_loop_quit(loop);
+}
+
+static void
+test_webkit_download_data(void)
+{
+ gboolean beenThere = FALSE;
+ WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+
+ g_signal_connect(webView, "download-requested",
+ G_CALLBACK(download_requested_cb),
+ &beenThere);
+
+ g_signal_connect(webView, "notify::load-status",
+ G_CALLBACK(idle_quit_loop_cb),
+ NULL);
+
+ g_signal_connect(webView, "mime-type-policy-decision-requested",
+ G_CALLBACK(mime_type_policy_decision_requested_cb),
+ NULL);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ /* We're testing for a crash, so just not crashing is a pass */
+ webkit_web_view_load_uri(webView, "data:application/octect-stream,");
+ g_main_loop_run(loop);
+
+ g_assert_cmpint(beenThere, ==, TRUE);
+
+ g_main_loop_unref(loop);
+ g_object_unref(webView);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/download/create", test_webkit_download_create);
+ g_test_add_func("/webkit/download/synch", test_webkit_download_synch);
+ g_test_add_func("/webkit/download/asynch", test_webkit_download_asynch);
+ g_test_add_func("/webkit/download/data", test_webkit_download_data);
+ return g_test_run ();
+}
+
+#else
+
+int main(int argc, char** argv)
+{
+ g_critical("You will need at least GTK+ 2.14.0 to run the unit tests.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testglobals.c b/Source/WebKit/gtk/tests/testglobals.c
new file mode 100644
index 0000000..da0ffa3
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testglobals.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <libsoup/soup.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+// Make sure the session is initialized properly when webkit_get_default_session() is called.
+static void test_globals_default_session()
+{
+ g_test_bug("36754");
+
+ SoupSession* session = webkit_get_default_session();
+ soup_session_remove_feature_by_type(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG);
+
+ // This makes sure our initialization ran.
+ g_assert(soup_session_get_feature(session, SOUP_TYPE_CONTENT_DECODER) != NULL);
+
+ // Creating a WebView should make sure the session is
+ // initialized, and not mess with our changes.
+ WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(web_view);
+ g_object_unref(web_view);
+
+ // These makes sure our modification was kept.
+ g_assert(soup_session_get_feature(session, SOUP_TYPE_CONTENT_DECODER) != NULL);
+ g_assert(soup_session_get_feature(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG) == NULL);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/globals/default_session",
+ test_globals_default_session);
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testhittestresult.c b/Source/WebKit/gtk/tests/testhittestresult.c
new file mode 100644
index 0000000..0d7fb05
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testhittestresult.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2009 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <glib/gstdio.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+typedef struct {
+ char* data;
+ guint flag;
+} TestInfo;
+
+static GMainLoop* loop;
+
+typedef struct {
+ WebKitWebView* webView;
+ TestInfo* info;
+} HitTestResultFixture;
+
+TestInfo*
+test_info_new(const char* data, guint flag)
+{
+ TestInfo* info;
+
+ info = g_slice_new(TestInfo);
+ info->data = g_strdup(data);
+ info->flag = flag;
+
+ return info;
+}
+
+void
+test_info_destroy(TestInfo* info)
+{
+ g_free(info->data);
+ g_slice_free(TestInfo, info);
+}
+
+static void hit_test_result_fixture_setup(HitTestResultFixture* fixture, gconstpointer data)
+{
+ fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(fixture->webView);
+ loop = g_main_loop_new(NULL, TRUE);
+ fixture->info = (TestInfo*)data;
+}
+
+static void hit_test_result_fixture_teardown(HitTestResultFixture* fixture, gconstpointer data)
+{
+ g_object_unref(fixture->webView);
+ g_main_loop_unref(loop);
+ test_info_destroy(fixture->info);
+}
+
+static void
+load_status_cb(WebKitWebView* webView,
+ GParamSpec* spec,
+ gpointer data)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ TestInfo* info = (TestInfo*)data;
+
+ if (status == WEBKIT_LOAD_FINISHED) {
+ WebKitHitTestResult* result;
+ guint context;
+ GdkEvent* event = gdk_event_new(GDK_BUTTON_PRESS);
+ WebKitDOMNode* node;
+
+ /* Close enough to 0,0 */
+ event->button.x = 5;
+ event->button.y = 5;
+
+ result = webkit_web_view_get_hit_test_result(webView, (GdkEventButton*) event);
+ gdk_event_free(event);
+ g_assert(result);
+
+ g_object_get(result, "context", &context, NULL);
+ g_assert(context & info->flag);
+
+ g_object_get(result, "inner-node", &node, NULL);
+ g_assert(node);
+ g_assert(WEBKIT_DOM_IS_NODE(node));
+ /* We can only test these node types at the moment. In the
+ * input case there seems to be an extra layer with a DIV on
+ * top of the input, which gets assigned to the inner-node.
+ * tag */
+ if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT)
+ g_assert(WEBKIT_DOM_IS_HTML_HTML_ELEMENT(node));
+ else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE)
+ g_assert(WEBKIT_DOM_IS_HTML_IMAGE_ELEMENT(node));
+ else if (info->flag == WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) {
+ /* The hit test will give us the inner text node, we want
+ * the A tag */
+ WebKitDOMNode* parent = webkit_dom_node_get_parent_node(node);
+ g_assert(WEBKIT_DOM_IS_HTML_ANCHOR_ELEMENT(parent));
+ }
+
+ g_object_unref(result);
+ g_main_loop_quit(loop);
+ }
+}
+
+static void
+test_webkit_hit_test_result(HitTestResultFixture* fixture, gconstpointer data)
+{
+ TestInfo* info = (TestInfo*)data;
+ GtkAllocation allocation = { 0, 0, 50, 50 };
+
+ webkit_web_view_load_string(fixture->webView,
+ info->data,
+ "text/html",
+ "utf-8",
+ "file://");
+ gtk_widget_size_allocate(GTK_WIDGET(fixture->webView), &allocation);
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_status_cb), info);
+ g_main_loop_run(loop);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+
+ g_test_add("/webkit/hittestresult/document", HitTestResultFixture,
+ test_info_new("<html><body><h1>WebKitGTK+!</h1></body></html>",
+ WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT),
+ hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown);
+ /* We hardcode all elements to be at 0,0 so that we know where to
+ * generate the button events */
+ g_test_add("/webkit/hittestresult/image", HitTestResultFixture,
+ test_info_new("<html><body><img style='position:absolute; left:0; top:0'src='0xdeadbeef' width=50 height=50></img></body></html>",
+ WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE),
+ hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown);
+ g_test_add("/webkit/hittestresult/editable", HitTestResultFixture,
+ test_info_new("<html><body><input style='position:absolute; left:0; top:0' size='35'></input>></body></html>",
+ WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE),
+ hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown);
+ g_test_add("/webkit/hittestresult/link", HitTestResultFixture,
+ test_info_new("<html><body><a style='position:absolute; left:0; top:0' href='http://www.example.com'>HELLO WORLD</a></body></html>",
+ WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK),
+ hit_test_result_fixture_setup, test_webkit_hit_test_result, hit_test_result_fixture_teardown);
+
+ return g_test_run ();
+}
+
+#else
+
+int main(int argc, char** argv)
+{
+ g_critical("You will need at least GTK+ 2.14.0 to run the unit tests.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testhttpbackend.c b/Source/WebKit/gtk/tests/testhttpbackend.c
new file mode 100644
index 0000000..f0fac16
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testhttpbackend.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2009 Gustavo Noronha Silva
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+// Not yet public API
+SoupMessage* webkit_network_request_get_message(WebKitNetworkRequest* request);
+
+static gboolean navigation_policy_decision_requested_cb(WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ WebKitNetworkRequest* request,
+ WebKitWebNavigationAction* action,
+ WebKitWebPolicyDecision* decision,
+ gpointer data)
+{
+ SoupMessage* message = webkit_network_request_get_message(request);
+
+ /* 1 -> webkit_network_request_with_core_request
+ *
+ * The SoupMessage is created exclusively for the emission of this
+ * signal.
+ */
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1);
+
+ return FALSE;
+}
+
+static void test_soup_message_lifetime()
+{
+ WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+
+ g_object_ref_sink(web_view);
+
+ g_signal_connect(web_view, "navigation-policy-decision-requested",
+ G_CALLBACK(navigation_policy_decision_requested_cb),
+ NULL);
+
+ /* load_uri will trigger the navigation-policy-decision-requested
+ * signal emission;
+ */
+ webkit_web_view_load_uri(web_view, "http://127.0.0.1/");
+
+ g_object_unref(web_view);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/soupmessage/lifetime", test_soup_message_lifetime);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testkeyevents.c b/Source/WebKit/gtk/tests/testkeyevents.c
new file mode 100644
index 0000000..b41a032
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testkeyevents.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2009, 2010 Martin Robinson <mrobinson@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <glib/gstdio.h>
+#include <webkit/webkit.h>
+#include <JavaScriptCore/JSStringRef.h>
+#include <JavaScriptCore/JSContextRef.h>
+
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+typedef struct {
+ char* page;
+ char* text;
+ gboolean shouldBeHandled;
+} TestInfo;
+
+typedef struct {
+ GtkWidget* window;
+ WebKitWebView* webView;
+ GMainLoop* loop;
+ TestInfo* info;
+} KeyEventFixture;
+
+TestInfo*
+test_info_new(const char* page, gboolean shouldBeHandled)
+{
+ TestInfo* info;
+
+ info = g_slice_new(TestInfo);
+ info->page = g_strdup(page);
+ info->shouldBeHandled = shouldBeHandled;
+ info->text = 0;
+
+ return info;
+}
+
+void
+test_info_destroy(TestInfo* info)
+{
+ g_free(info->page);
+ g_free(info->text);
+ g_slice_free(TestInfo, info);
+}
+
+static void key_event_fixture_setup(KeyEventFixture* fixture, gconstpointer data)
+{
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+
+ fixture->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+
+ gtk_container_add(GTK_CONTAINER(fixture->window), GTK_WIDGET(fixture->webView));
+}
+
+static void key_event_fixture_teardown(KeyEventFixture* fixture, gconstpointer data)
+{
+ gtk_widget_destroy(fixture->window);
+ g_main_loop_unref(fixture->loop);
+ test_info_destroy(fixture->info);
+}
+
+static gboolean key_press_event_cb(WebKitWebView* webView, GdkEvent* event, gpointer data)
+{
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ gboolean handled = GTK_WIDGET_GET_CLASS(fixture->webView)->key_press_event(GTK_WIDGET(fixture->webView), &event->key);
+ g_assert_cmpint(handled, ==, fixture->info->shouldBeHandled);
+
+ return FALSE;
+}
+
+static gboolean key_release_event_cb(WebKitWebView* webView, GdkEvent* event, gpointer data)
+{
+ // WebCore never seems to mark keyup events as handled.
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ gboolean handled = GTK_WIDGET_GET_CLASS(fixture->webView)->key_press_event(GTK_WIDGET(fixture->webView), &event->key);
+ g_assert(!handled);
+
+ g_main_loop_quit(fixture->loop);
+
+ return FALSE;
+}
+
+static void test_keypress_events_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
+{
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status == WEBKIT_LOAD_FINISHED) {
+ g_signal_connect(fixture->webView, "key-press-event",
+ G_CALLBACK(key_press_event_cb), fixture);
+ g_signal_connect(fixture->webView, "key-release-event",
+ G_CALLBACK(key_release_event_cb), fixture);
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('a'), 0))
+ g_assert_not_reached();
+ }
+
+}
+
+gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data)
+{
+ gtk_widget_grab_focus(widget);
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ webkit_web_view_load_string(fixture->webView, fixture->info->page,
+ "text/html", "utf-8", "file://");
+ return FALSE;
+}
+
+static void setup_keyevent_test(KeyEventFixture* fixture, gconstpointer data, GCallback load_event_callback)
+{
+ fixture->info = (TestInfo*)data;
+ g_signal_connect(fixture->window, "map-event",
+ G_CALLBACK(map_event_cb), fixture);
+
+ gtk_widget_show(fixture->window);
+ gtk_widget_show(GTK_WIDGET(fixture->webView));
+ gtk_window_present(GTK_WINDOW(fixture->window));
+
+ g_signal_connect(fixture->webView, "notify::load-status",
+ load_event_callback, fixture);
+
+ g_main_loop_run(fixture->loop);
+}
+
+static void test_keypress_events(KeyEventFixture* fixture, gconstpointer data)
+{
+ setup_keyevent_test(fixture, data, G_CALLBACK(test_keypress_events_load_status_cb));
+}
+
+static gboolean element_text_equal_to(JSContextRef context, const gchar* text)
+{
+ JSStringRef scriptString = JSStringCreateWithUTF8CString(
+ "window.document.getElementById(\"in\").value;");
+ JSValueRef value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0);
+ JSStringRelease(scriptString);
+
+ // If the value isn't a string, the element is probably a div
+ // so grab the innerText instead.
+ if (!JSValueIsString(context, value)) {
+ JSStringRef scriptString = JSStringCreateWithUTF8CString(
+ "window.document.getElementById(\"in\").innerText;");
+ value = JSEvaluateScript(context, scriptString, 0, 0, 0, 0);
+ JSStringRelease(scriptString);
+ }
+
+ g_assert(JSValueIsString(context, value));
+ JSStringRef inputString = JSValueToStringCopy(context, value, 0);
+ g_assert(inputString);
+
+ gint size = JSStringGetMaximumUTF8CStringSize(inputString);
+ gchar* cString = g_malloc(size);
+ JSStringGetUTF8CString(inputString, cString, size);
+ JSStringRelease(inputString);
+
+ gboolean result = g_utf8_collate(cString, text) == 0;
+ g_free(cString);
+ return result;
+}
+
+static void test_ime_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
+{
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ JSGlobalContextRef context = webkit_web_frame_get_global_context(
+ webkit_web_view_get_main_frame(webView));
+ g_assert(context);
+
+ GtkIMContext* imContext = 0;
+ g_object_get(webView, "im-context", &imContext, NULL);
+ g_assert(imContext);
+
+ // Test that commits that happen outside of key events
+ // change the text field immediately. This closely replicates
+ // the behavior of SCIM.
+ g_assert(element_text_equal_to(context, ""));
+ g_signal_emit_by_name(imContext, "commit", "a");
+ g_assert(element_text_equal_to(context, "a"));
+ g_signal_emit_by_name(imContext, "commit", "b");
+ g_assert(element_text_equal_to(context, "ab"));
+ g_signal_emit_by_name(imContext, "commit", "c");
+ g_assert(element_text_equal_to(context, "abc"));
+
+ g_object_unref(imContext);
+ g_main_loop_quit(fixture->loop);
+}
+
+static void test_ime(KeyEventFixture* fixture, gconstpointer data)
+{
+ setup_keyevent_test(fixture, data, G_CALLBACK(test_ime_load_status_cb));
+}
+
+static gboolean verify_contents(gpointer data)
+{
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ JSGlobalContextRef context = webkit_web_frame_get_global_context(
+ webkit_web_view_get_main_frame(fixture->webView));
+ g_assert(context);
+
+ g_assert(element_text_equal_to(context, fixture->info->text));
+ g_main_loop_quit(fixture->loop);
+ return FALSE;
+}
+
+static void test_blocking_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
+{
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ // The first keypress event should not modify the field.
+ fixture->info->text = g_strdup("bc");
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('a'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('b'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('c'), 0))
+ g_assert_not_reached();
+
+ g_idle_add(verify_contents, fixture);
+}
+
+static void test_blocking(KeyEventFixture* fixture, gconstpointer data)
+{
+ setup_keyevent_test(fixture, data, G_CALLBACK(test_blocking_load_status_cb));
+}
+
+#if defined(GDK_WINDOWING_X11) && GTK_CHECK_VERSION(2, 16, 0)
+static void test_xim_load_status_cb(WebKitWebView* webView, GParamSpec* spec, gpointer data)
+{
+ KeyEventFixture* fixture = (KeyEventFixture*)data;
+ WebKitLoadStatus status = webkit_web_view_get_load_status(webView);
+ if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ GtkIMContext* imContext = 0;
+ g_object_get(webView, "im-context", &imContext, NULL);
+ g_assert(imContext);
+
+ gchar* originalId = g_strdup(gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(imContext)));
+ gtk_im_multicontext_set_context_id(GTK_IM_MULTICONTEXT(imContext), "xim");
+
+ // Test that commits that happen outside of key events
+ // change the text field immediately. This closely replicates
+ // the behavior of SCIM.
+ fixture->info->text = g_strdup("debian");
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('d'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('e'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('b'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('i'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('a'), 0))
+ g_assert_not_reached();
+ if (!gtk_test_widget_send_key(GTK_WIDGET(fixture->webView),
+ gdk_unicode_to_keyval('n'), 0))
+ g_assert_not_reached();
+
+ gtk_im_multicontext_set_context_id(GTK_IM_MULTICONTEXT(imContext), originalId);
+ g_free(originalId);
+ g_object_unref(imContext);
+
+ g_idle_add(verify_contents, fixture);
+}
+
+static void test_xim(KeyEventFixture* fixture, gconstpointer data)
+{
+ setup_keyevent_test(fixture, data, G_CALLBACK(test_xim_load_status_cb));
+}
+#endif
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+
+
+ // We'll test input on a slew of different node types. Key events to
+ // text inputs and editable divs should be marked as handled. Key events
+ // to buttons and links should not.
+ const char* textinput_html = "<html><body><input id=\"in\" type=\"text\">"
+ "<script>document.getElementById('in').focus();</script></body></html>";
+ const char* button_html = "<html><body><input id=\"in\" type=\"button\">"
+ "<script>document.getElementById('in').focus();</script></body></html>";
+ const char* link_html = "<html><body><a href=\"http://www.gnome.org\" id=\"in\">"
+ "LINKY MCLINKERSON</a><script>document.getElementById('in').focus();</script>"
+ "</body></html>";
+ const char* div_html = "<html><body><div id=\"in\" contenteditable=\"true\">"
+ "<script>document.getElementById('in').focus();</script></body></html>";
+
+ // These are similar to the blocks above, but they should block the first
+ // keypress modifying the editable node.
+ const char* textinput_html_blocking = "<html><body>"
+ "<input id=\"in\" type=\"text\" "
+ "onkeypress=\"if (first) {event.preventDefault();first=false;}\">"
+ "<script>first = true;\ndocument.getElementById('in').focus();</script>\n"
+ "</script></body></html>";
+ const char* div_html_blocking = "<html><body>"
+ "<div id=\"in\" contenteditable=\"true\" "
+ "onkeypress=\"if (first) {event.preventDefault();first=false;}\">"
+ "<script>first = true; document.getElementById('in').focus();</script>\n"
+ "</script></body></html>";
+
+ g_test_add("/webkit/keyevents/event-textinput", KeyEventFixture,
+ test_info_new(textinput_html, TRUE),
+ key_event_fixture_setup,
+ test_keypress_events,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevents/event-buttons", KeyEventFixture,
+ test_info_new(button_html, FALSE),
+ key_event_fixture_setup,
+ test_keypress_events,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevents/event-link", KeyEventFixture,
+ test_info_new(link_html, FALSE),
+ key_event_fixture_setup,
+ test_keypress_events,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevent/event-div", KeyEventFixture,
+ test_info_new(div_html, TRUE),
+ key_event_fixture_setup,
+ test_keypress_events,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevent/ime-textinput", KeyEventFixture,
+ test_info_new(textinput_html, TRUE),
+ key_event_fixture_setup,
+ test_ime,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevent/ime-div", KeyEventFixture,
+ test_info_new(div_html, TRUE),
+ key_event_fixture_setup,
+ test_ime,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevent/block-textinput", KeyEventFixture,
+ test_info_new(textinput_html_blocking, TRUE),
+ key_event_fixture_setup,
+ test_blocking,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevent/block-div", KeyEventFixture,
+ test_info_new(div_html_blocking, TRUE),
+ key_event_fixture_setup,
+ test_blocking,
+ key_event_fixture_teardown);
+#if defined(GDK_WINDOWING_X11) && GTK_CHECK_VERSION(2, 16, 0)
+ g_test_add("/webkit/keyevent/xim-textinput", KeyEventFixture,
+ test_info_new(textinput_html, TRUE),
+ key_event_fixture_setup,
+ test_xim,
+ key_event_fixture_teardown);
+ g_test_add("/webkit/keyevent/xim-div", KeyEventFixture,
+ test_info_new(div_html, TRUE),
+ key_event_fixture_setup,
+ test_xim,
+ key_event_fixture_teardown);
+#endif
+
+ return g_test_run();
+}
+
+#else
+
+int main(int argc, char** argv)
+{
+ g_critical("You will need at least GTK+ 2.14.0 to run the unit tests.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testloading.c b/Source/WebKit/gtk/tests/testloading.c
new file mode 100644
index 0000000..a0ec8c9
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testloading.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2009, 2010 Gustavo Noronha Silva
+ * Copyright (C) 2009 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <libsoup/soup.h>
+#include <string.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+/* This string has to be rather big because of the cancelled test - it
+ * looks like soup refuses to send or receive a too small chunk */
+#define HTML_STRING "<html><body>Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!Testing!</body></html>"
+
+SoupURI* base_uri;
+
+/* For real request testing */
+static void
+server_callback(SoupServer* server, SoupMessage* msg,
+ const char* path, GHashTable* query,
+ SoupClientContext* context, gpointer data)
+{
+ if (msg->method != SOUP_METHOD_GET) {
+ soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ soup_message_set_status(msg, SOUP_STATUS_OK);
+
+ if (g_str_equal(path, "/test_loading_status") || g_str_equal(path, "/test_loading_status2"))
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_STATIC, HTML_STRING, strlen(HTML_STRING));
+ else if (g_str_equal(path, "/test_load_error")) {
+ soup_message_set_status(msg, SOUP_STATUS_CANT_CONNECT);
+ } else if (g_str_equal(path, "/test_loading_cancelled")) {
+ soup_message_headers_set_encoding(msg->response_headers, SOUP_ENCODING_CHUNKED);
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_STATIC, HTML_STRING, strlen(HTML_STRING));
+ soup_server_unpause_message(server, msg);
+ return;
+ }
+
+ soup_message_body_complete(msg->response_body);
+}
+
+typedef struct {
+ WebKitWebView* webView;
+ GMainLoop *loop;
+ gboolean has_been_provisional;
+ gboolean has_been_committed;
+ gboolean has_been_first_visually_non_empty_layout;
+ gboolean has_been_finished;
+ gboolean has_been_failed;
+ gboolean has_been_load_error;
+} WebLoadingFixture;
+
+static void web_loading_fixture_setup(WebLoadingFixture* fixture, gconstpointer data)
+{
+ fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ fixture->loop = g_main_loop_new(NULL, TRUE);
+ g_object_ref_sink(fixture->webView);
+ fixture->has_been_provisional = FALSE;
+ fixture->has_been_committed = FALSE;
+ fixture->has_been_first_visually_non_empty_layout = FALSE;
+ fixture->has_been_finished = FALSE;
+ fixture->has_been_failed = FALSE;
+ fixture->has_been_load_error = FALSE;
+}
+
+static void web_loading_fixture_teardown(WebLoadingFixture* fixture, gconstpointer data)
+{
+ g_object_unref(fixture->webView);
+ g_main_loop_unref(fixture->loop);
+}
+
+static char* get_uri_for_path(const char* path)
+{
+ SoupURI* uri;
+ char* uri_string;
+
+ uri = soup_uri_new_with_base(base_uri, path);
+ uri_string = soup_uri_to_string(uri, FALSE);
+ soup_uri_free (uri);
+
+ return uri_string;
+}
+
+static void load_finished_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebLoadingFixture* fixture)
+{
+ g_assert(fixture->has_been_provisional);
+ g_assert(fixture->has_been_committed);
+ g_assert(fixture->has_been_first_visually_non_empty_layout);
+
+ g_main_loop_quit(fixture->loop);
+}
+
+
+static void status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
+
+ switch (status) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ g_assert(!fixture->has_been_provisional);
+ g_assert(!fixture->has_been_committed);
+ g_assert(!fixture->has_been_first_visually_non_empty_layout);
+ fixture->has_been_provisional = TRUE;
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ g_assert(fixture->has_been_provisional);
+ g_assert(!fixture->has_been_committed);
+ g_assert(!fixture->has_been_first_visually_non_empty_layout);
+ fixture->has_been_committed = TRUE;
+ break;
+ case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT:
+ g_assert(fixture->has_been_provisional);
+ g_assert(fixture->has_been_committed);
+ g_assert(!fixture->has_been_first_visually_non_empty_layout);
+ fixture->has_been_first_visually_non_empty_layout = TRUE;
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ g_assert(fixture->has_been_provisional);
+ g_assert(fixture->has_been_committed);
+ g_assert(fixture->has_been_first_visually_non_empty_layout);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static void test_loading_status(WebLoadingFixture* fixture, gconstpointer data)
+{
+ char* uri_string;
+
+ g_assert_cmpint(webkit_web_view_get_load_status(fixture->webView), ==, WEBKIT_LOAD_PROVISIONAL);
+
+ g_object_connect(G_OBJECT(fixture->webView),
+ "signal::notify::load-status", G_CALLBACK(status_changed_cb), fixture,
+ "signal::load-finished", G_CALLBACK(load_finished_cb), fixture,
+ NULL);
+
+ uri_string = get_uri_for_path("/test_loading_status");
+
+ /* load_uri will trigger the navigation-policy-decision-requested
+ * signal emission;
+ */
+ webkit_web_view_load_uri(fixture->webView, uri_string);
+ g_free(uri_string);
+
+ g_main_loop_run(fixture->loop);
+}
+
+static void load_error_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
+
+ switch(status) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ g_assert(!fixture->has_been_provisional);
+ fixture->has_been_provisional = TRUE;
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ g_assert(!fixture->has_been_committed);
+ fixture->has_been_committed = TRUE;
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ g_assert(fixture->has_been_provisional);
+ g_assert(fixture->has_been_load_error);
+ g_assert(fixture->has_been_failed);
+ g_assert(!fixture->has_been_finished);
+ fixture->has_been_finished = TRUE;
+ break;
+ case WEBKIT_LOAD_FAILED:
+ g_assert(!fixture->has_been_failed);
+ fixture->has_been_failed = TRUE;
+ g_main_loop_quit(fixture->loop);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean load_error_cb(WebKitWebView* webView, WebKitWebFrame* frame, const char* uri, GError *error, WebLoadingFixture* fixture)
+{
+ g_assert(fixture->has_been_provisional);
+ g_assert(!fixture->has_been_load_error);
+ fixture->has_been_load_error = TRUE;
+
+ return FALSE;
+}
+
+static void test_loading_error(WebLoadingFixture* fixture, gconstpointer data)
+{
+ char* uri_string;
+
+ g_test_bug("28842");
+
+ g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_error_cb), fixture);
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_error_status_changed_cb), fixture);
+
+ uri_string = get_uri_for_path("/test_load_error");
+ webkit_web_view_load_uri(fixture->webView, uri_string);
+ g_free(uri_string);
+
+ g_main_loop_run(fixture->loop);
+
+ g_assert(fixture->has_been_provisional);
+ g_assert(!fixture->has_been_committed);
+ g_assert(fixture->has_been_load_error);
+ g_assert(fixture->has_been_failed);
+ g_assert(!fixture->has_been_finished);
+}
+
+/* Cancelled load */
+
+static gboolean load_cancelled_cb(WebKitWebView* webView, WebKitWebFrame* frame, const char* uri, GError *error, WebLoadingFixture* fixture)
+{
+ g_assert(fixture->has_been_provisional);
+ g_assert(fixture->has_been_failed);
+ g_assert(!fixture->has_been_load_error);
+ g_assert(error->code == WEBKIT_NETWORK_ERROR_CANCELLED);
+ fixture->has_been_load_error = TRUE;
+
+ return TRUE;
+}
+
+static gboolean stop_load (gpointer data)
+{
+ webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(data));
+ return FALSE;
+}
+
+static void load_cancelled_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
+
+ switch(status) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ g_assert(!fixture->has_been_provisional);
+ g_assert(!fixture->has_been_failed);
+ fixture->has_been_provisional = TRUE;
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ g_idle_add (stop_load, object);
+ break;
+ case WEBKIT_LOAD_FAILED:
+ g_assert(fixture->has_been_provisional);
+ g_assert(!fixture->has_been_failed);
+ g_assert(!fixture->has_been_load_error);
+ fixture->has_been_failed = TRUE;
+ g_main_loop_quit(fixture->loop);
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ g_assert_not_reached();
+ break;
+ default:
+ break;
+ }
+}
+
+static void test_loading_cancelled(WebLoadingFixture* fixture, gconstpointer data)
+{
+ char* uri_string;
+
+ g_test_bug("29644");
+
+ g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_cancelled_cb), fixture);
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_cancelled_status_changed_cb), fixture);
+
+ uri_string = get_uri_for_path("/test_loading_cancelled");
+ webkit_web_view_load_uri(fixture->webView, uri_string);
+ g_free(uri_string);
+
+ g_main_loop_run(fixture->loop);
+}
+
+static void load_goback_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
+
+ switch(status) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ g_assert(!fixture->has_been_provisional);
+ fixture->has_been_provisional = TRUE;
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ g_assert(fixture->has_been_provisional);
+ fixture->has_been_committed = TRUE;
+ break;
+ case WEBKIT_LOAD_FAILED:
+ g_assert_not_reached();
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ g_assert(fixture->has_been_provisional);
+ g_assert(fixture->has_been_committed);
+ fixture->has_been_finished = TRUE;
+ g_main_loop_quit(fixture->loop);
+ break;
+ default:
+ break;
+ }
+}
+
+static void load_wentback_status_changed_cb(GObject* object, GParamSpec* pspec, WebLoadingFixture* fixture)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(WEBKIT_WEB_VIEW(object));
+ char* uri_string;
+ char* uri_string2;
+
+ uri_string = get_uri_for_path("/test_loading_status");
+ uri_string2 = get_uri_for_path("/test_loading_status2");
+
+ switch(status) {
+ case WEBKIT_LOAD_PROVISIONAL:
+ g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string2);
+ break;
+ case WEBKIT_LOAD_COMMITTED:
+ g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string);
+ break;
+ case WEBKIT_LOAD_FAILED:
+ g_assert_not_reached();
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ g_assert_cmpstr(webkit_web_view_get_uri(fixture->webView), ==, uri_string);
+ g_main_loop_quit(fixture->loop);
+ break;
+ default:
+ break;
+ }
+
+ g_free(uri_string);
+ g_free(uri_string2);
+}
+
+static void load_error_test(WebKitWebView* webview, WebKitWebFrame* frame, const char* uri, GError* error)
+{
+ g_debug("Error: %s", error->message);
+}
+
+static void test_loading_goback(WebLoadingFixture* fixture, gconstpointer data)
+{
+ char* uri_string;
+
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_goback_status_changed_cb), fixture);
+
+ g_signal_connect(fixture->webView, "load-error", G_CALLBACK(load_error_test), fixture);
+
+ uri_string = get_uri_for_path("/test_loading_status");
+ webkit_web_view_load_uri(fixture->webView, uri_string);
+ g_free(uri_string);
+
+ g_main_loop_run(fixture->loop);
+
+ fixture->has_been_provisional = FALSE;
+ fixture->has_been_committed = FALSE;
+ fixture->has_been_first_visually_non_empty_layout = FALSE;
+ fixture->has_been_finished = FALSE;
+ fixture->has_been_failed = FALSE;
+ fixture->has_been_load_error = FALSE;
+
+ uri_string = get_uri_for_path("/test_loading_status2");
+ webkit_web_view_load_uri(fixture->webView, uri_string);
+ g_free(uri_string);
+
+ g_main_loop_run(fixture->loop);
+
+ g_signal_handlers_disconnect_by_func(fixture->webView, load_goback_status_changed_cb, fixture);
+
+ fixture->has_been_provisional = FALSE;
+ fixture->has_been_committed = FALSE;
+ fixture->has_been_first_visually_non_empty_layout = FALSE;
+ fixture->has_been_finished = FALSE;
+ fixture->has_been_failed = FALSE;
+ fixture->has_been_load_error = FALSE;
+
+ g_signal_connect(fixture->webView, "notify::load-status", G_CALLBACK(load_wentback_status_changed_cb), fixture);
+ webkit_web_view_go_back(fixture->webView);
+
+ g_main_loop_run(fixture->loop);
+
+ g_signal_handlers_disconnect_by_func(fixture->webView, load_wentback_status_changed_cb, fixture);
+}
+
+int main(int argc, char** argv)
+{
+ SoupServer* server;
+
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
+ soup_server_run_async(server);
+
+ soup_server_add_handler(server, NULL, server_callback, NULL, NULL);
+
+ base_uri = soup_uri_new("http://127.0.0.1/");
+ soup_uri_set_port(base_uri, soup_server_get_port(server));
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add("/webkit/loading/status",
+ WebLoadingFixture, NULL,
+ web_loading_fixture_setup,
+ test_loading_status,
+ web_loading_fixture_teardown);
+ g_test_add("/webkit/loading/error",
+ WebLoadingFixture, NULL,
+ web_loading_fixture_setup,
+ test_loading_error,
+ web_loading_fixture_teardown);
+ g_test_add("/webkit/loading/cancelled",
+ WebLoadingFixture, NULL,
+ web_loading_fixture_setup,
+ test_loading_cancelled,
+ web_loading_fixture_teardown);
+ g_test_add("/webkit/loading/goback",
+ WebLoadingFixture, NULL,
+ web_loading_fixture_setup,
+ test_loading_goback,
+ web_loading_fixture_teardown);
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testmimehandling.c b/Source/WebKit/gtk/tests/testmimehandling.c
new file mode 100644
index 0000000..41e170a
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testmimehandling.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2009 Jan Michael Alonzo
+ * Copyright (C) 2009 Gustavo Noronha Silva
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "test_utils.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <libsoup/soup.h>
+#include <string.h>
+#include <webkit/webkit.h>
+#include <unistd.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+GMainLoop* loop;
+SoupSession *session;
+char* base_uri;
+
+/* For real request testing */
+static void
+server_callback(SoupServer *server, SoupMessage *msg,
+ const char *path, GHashTable *query,
+ SoupClientContext *context, gpointer data)
+{
+ if (msg->method != SOUP_METHOD_GET) {
+ soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ soup_message_set_status(msg, SOUP_STATUS_OK);
+
+ /* PDF */
+ if (g_str_equal(path, "/pdf")) {
+ char* contents;
+ gsize length;
+ GError* error = NULL;
+
+ g_file_get_contents("test.pdf", &contents, &length, &error);
+ g_assert(!error);
+
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length);
+ } else if (g_str_equal(path, "/html")) {
+ char* contents;
+ gsize length;
+ GError* error = NULL;
+
+ g_file_get_contents("test.html", &contents, &length, &error);
+ g_assert(!error);
+
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length);
+ } else if (g_str_equal(path, "/text")) {
+ char* contents;
+ gsize length;
+ GError* error = NULL;
+
+ soup_message_headers_append(msg->response_headers, "Content-Disposition", "attachment; filename=test.txt");
+
+ g_file_get_contents("test.txt", &contents, &length, &error);
+ g_assert(!error);
+
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length);
+ } else if (g_str_equal(path, "/ogg")) {
+ char* contents;
+ gsize length;
+ GError* error = NULL;
+
+ g_file_get_contents("test.ogg", &contents, &length, &error);
+ g_assert(!error);
+
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length);
+ }
+
+ soup_message_body_complete(msg->response_body);
+}
+
+static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED ||
+ webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED)
+ g_main_loop_quit(loop);
+}
+
+static gboolean mime_type_policy_decision_requested_cb(WebKitWebView* view, WebKitWebFrame* frame,
+ WebKitNetworkRequest* request, const char* mime_type,
+ WebKitWebPolicyDecision* decision, gpointer data)
+{
+ char* type = (char*)data;
+
+ if (g_str_equal(type, "pdf")) {
+ g_assert_cmpstr(mime_type, ==, "application/pdf");
+ g_assert(!webkit_web_view_can_show_mime_type(view, mime_type));
+ } else if (g_str_equal(type, "html")) {
+ g_assert_cmpstr(mime_type, ==, "text/html");
+ g_assert(webkit_web_view_can_show_mime_type(view, mime_type));
+ } else if (g_str_equal(type, "text")) {
+ WebKitNetworkResponse* response = webkit_web_frame_get_network_response(frame);
+ SoupMessage* message = webkit_network_response_get_message(response);
+ char* disposition;
+
+ g_assert(message);
+ soup_message_headers_get_content_disposition(message->response_headers,
+ &disposition, NULL);
+ g_object_unref(response);
+
+ g_assert_cmpstr(disposition, ==, "attachment");
+ g_free(disposition);
+
+ g_assert_cmpstr(mime_type, ==, "text/plain");
+ g_assert(webkit_web_view_can_show_mime_type(view, mime_type));
+ } else if (g_str_equal(type, "ogg")) {
+ g_assert_cmpstr(mime_type, ==, "audio/x-vorbis+ogg");
+ g_assert(webkit_web_view_can_show_mime_type(view, mime_type));
+ }
+
+ g_free(type);
+
+ return FALSE;
+}
+
+static void testRemoteMimeType(const void* data)
+{
+ const char* name = (const char*) data;
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(G_OBJECT(view));
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_connect(G_OBJECT(view),
+ "signal::notify::load-status", idle_quit_loop_cb, NULL,
+ "signal::mime-type-policy-decision-requested", mime_type_policy_decision_requested_cb, g_strdup(name),
+ NULL);
+
+ char* effective_uri = g_strdup_printf("%s%s", base_uri, name);
+ webkit_web_view_load_uri(view, effective_uri);
+ g_free(effective_uri);
+
+ g_main_loop_run(loop);
+
+ g_object_unref(view);
+}
+
+static void testLocalMimeType(const void* data)
+{
+ const char* typeName = (const char*) data;
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(G_OBJECT(view));
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_connect(G_OBJECT(view),
+ "signal::notify::load-status", idle_quit_loop_cb, NULL,
+ "signal::mime-type-policy-decision-requested", mime_type_policy_decision_requested_cb, g_strdup(typeName),
+ NULL);
+
+ gchar* filename = g_strdup_printf("test.%s", typeName);
+ GFile* file = g_file_new_for_path(filename);
+ g_free(filename);
+
+ gchar* fileURI = g_file_get_uri(file);
+ g_object_unref(file);
+
+ webkit_web_view_load_uri(view, fileURI);
+ g_free(fileURI);
+
+ g_main_loop_run(loop);
+ g_object_unref(view);
+}
+
+int main(int argc, char** argv)
+{
+ SoupServer* server;
+ SoupURI* soup_uri;
+
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ /* Hopefully make test independent of the path it's called from. */
+ testutils_relative_chdir("Source/WebKit/gtk/tests/resources/test.html", argv[0]);
+
+ server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
+ soup_server_run_async(server);
+
+ soup_server_add_handler(server, NULL, server_callback, NULL, NULL);
+
+ soup_uri = soup_uri_new("http://127.0.0.1/");
+ soup_uri_set_port(soup_uri, soup_server_get_port(server));
+
+ base_uri = soup_uri_to_string(soup_uri, FALSE);
+ soup_uri_free(soup_uri);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_data_func("/webkit/mime/remote-PDF", "pdf", testRemoteMimeType);
+ g_test_add_data_func("/webkit/mime/remote-HTML", "html", testRemoteMimeType);
+ g_test_add_data_func("/webkit/mime/remote-TEXT", "text", testRemoteMimeType);
+ g_test_add_data_func("/webkit/mime/remote-OGG", "ogg", testRemoteMimeType);
+ g_test_add_data_func("/webkit/mime/local-PDF", "pdf", testLocalMimeType);
+ g_test_add_data_func("/webkit/mime/local-HTML", "html", testLocalMimeType);
+ g_test_add_data_func("/webkit/mime/local-TEXT", "text", testLocalMimeType);
+ g_test_add_data_func("/webkit/mime/local-OGG", "ogg", testLocalMimeType);
+
+ return g_test_run();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testnetworkrequest.c b/Source/WebKit/gtk/tests/testnetworkrequest.c
new file mode 100644
index 0000000..fb6ec41
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testnetworkrequest.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2009 Gustavo Noronha Silva
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static void test_network_request_create_destroy()
+{
+ WebKitNetworkRequest* request;
+ SoupMessage* message;
+
+ /* Test creation with URI */
+ request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "uri", "http://debian.org/", NULL));
+ g_assert(WEBKIT_IS_NETWORK_REQUEST(request));
+ message = webkit_network_request_get_message(request);
+ g_assert(!message);
+ g_object_unref(request);
+
+ /* Test creation with SoupMessage */
+ message = soup_message_new("GET", "http://debian.org/");
+ request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "message", message, NULL));
+ g_assert(WEBKIT_IS_NETWORK_REQUEST(request));
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2);
+ g_object_unref(request);
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1);
+ g_object_unref(message);
+
+ /* Test creation with both SoupMessage and URI */
+ message = soup_message_new("GET", "http://debian.org/");
+ request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "message", message, "uri", "http://gnome.org/", NULL));
+ g_assert(WEBKIT_IS_NETWORK_REQUEST(request));
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2);
+ g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://gnome.org/");
+ g_object_unref(request);
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1);
+ g_object_unref(message);
+}
+
+static void test_network_request_properties()
+{
+ WebKitNetworkRequest* request;
+ SoupMessage* message;
+ gchar* soupURI;
+
+ /* Test URI is set correctly when creating with URI */
+ request = webkit_network_request_new("http://debian.org/");
+ g_assert(WEBKIT_IS_NETWORK_REQUEST(request));
+ g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://debian.org/");
+ g_object_unref(request);
+
+ /* Test URI is set correctly when creating with Message */
+ message = soup_message_new("GET", "http://debian.org/");
+ request = WEBKIT_NETWORK_REQUEST(g_object_new(WEBKIT_TYPE_NETWORK_REQUEST, "message", message, NULL));
+ g_assert(WEBKIT_IS_NETWORK_REQUEST(request));
+ g_object_unref(message);
+
+ message = webkit_network_request_get_message(request);
+ soupURI = soup_uri_to_string(soup_message_get_uri(message), FALSE);
+ g_assert_cmpstr(soupURI, ==, "http://debian.org/");
+ g_free(soupURI);
+
+ g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://debian.org/");
+ g_object_unref(request);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/networkrequest/createdestroy", test_network_request_create_destroy);
+ g_test_add_func("/webkit/networkrequest/properties", test_network_request_properties);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testnetworkresponse.c b/Source/WebKit/gtk/tests/testnetworkresponse.c
new file mode 100644
index 0000000..90062c6
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testnetworkresponse.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2009 Gustavo Noronha Silva
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static void test_network_response_create_destroy()
+{
+ WebKitNetworkResponse* response;
+ SoupMessage* message;
+
+ /* Test creation with URI */
+ response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "uri", "http://debian.org/", NULL));
+ g_assert(WEBKIT_IS_NETWORK_RESPONSE(response));
+ message = webkit_network_response_get_message(response);
+ g_assert(!message);
+ g_object_unref(response);
+
+ /* Test creation with SoupMessage */
+ message = soup_message_new("GET", "http://debian.org/");
+ response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "message", message, NULL));
+ g_assert(WEBKIT_IS_NETWORK_RESPONSE(response));
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2);
+ g_object_unref(response);
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1);
+ g_object_unref(message);
+
+ /* Test creation with both SoupMessage and URI */
+ message = soup_message_new("GET", "http://debian.org/");
+ response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "message", message, "uri", "http://gnome.org/", NULL));
+ g_assert(WEBKIT_IS_NETWORK_RESPONSE(response));
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 2);
+ g_assert_cmpstr(webkit_network_response_get_uri(response), ==, "http://gnome.org/");
+ g_object_unref(response);
+ g_assert_cmpint(G_OBJECT(message)->ref_count, ==, 1);
+ g_object_unref(message);
+}
+
+static void test_network_response_properties()
+{
+ WebKitNetworkResponse* response;
+ SoupMessage* message;
+ gchar* soupURI;
+
+ /* Test URI is set correctly when creating with URI */
+ response = webkit_network_response_new("http://debian.org/");
+ g_assert(WEBKIT_IS_NETWORK_RESPONSE(response));
+ g_assert_cmpstr(webkit_network_response_get_uri(response), ==, "http://debian.org/");
+ g_object_unref(response);
+
+ /* Test URI is set correctly when creating with Message */
+ message = soup_message_new("GET", "http://debian.org/");
+ response = WEBKIT_NETWORK_RESPONSE(g_object_new(WEBKIT_TYPE_NETWORK_RESPONSE, "message", message, NULL));
+ g_assert(WEBKIT_IS_NETWORK_RESPONSE(response));
+ g_object_unref(message);
+
+ message = webkit_network_response_get_message(response);
+ soupURI = soup_uri_to_string(soup_message_get_uri(message), FALSE);
+ g_assert_cmpstr(soupURI, ==, "http://debian.org/");
+ g_free(soupURI);
+
+ g_assert_cmpstr(webkit_network_response_get_uri(response), ==, "http://debian.org/");
+ g_object_unref(response);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/networkresponse/createdestroy", test_network_response_create_destroy);
+ g_test_add_func("/webkit/networkresponse/properties", test_network_response_properties);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebbackforwardlist.c b/Source/WebKit/gtk/tests/testwebbackforwardlist.c
new file mode 100644
index 0000000..b9e395e
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebbackforwardlist.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static void test_webkit_web_history_item_lifetime(void)
+{
+ WebKitWebView* webView;
+ WebKitWebBackForwardList* backForwardList;
+ WebKitWebHistoryItem* currentItem;
+ WebKitWebHistoryItem* forwardItem;
+ WebKitWebHistoryItem* backItem;
+ WebKitWebHistoryItem* nthItem;
+ WebKitWebHistoryItem* item1;
+ WebKitWebHistoryItem* item2;
+ WebKitWebHistoryItem* item3;
+ WebKitWebHistoryItem* item4;
+ GList* backList = NULL;
+ GList* forwardList = NULL;
+ g_test_bug("19898");
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ backForwardList = webkit_web_view_get_back_forward_list(webView);
+ g_assert_cmpint(G_OBJECT(backForwardList)->ref_count, ==, 1);
+
+ /* add test items */
+ item1 = webkit_web_history_item_new_with_data("http://example.com/1/", "Site 1");
+ webkit_web_back_forward_list_add_item(backForwardList, item1);
+ g_object_unref(item1);
+
+ item2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Site 2");
+ webkit_web_back_forward_list_add_item(backForwardList, item2);
+ g_object_unref(item2);
+
+ item3 = webkit_web_history_item_new_with_data("http://example.com/3/", "Site 3");
+ webkit_web_back_forward_list_add_item(backForwardList, item3);
+ g_object_unref(item3);
+
+ item4 = webkit_web_history_item_new_with_data("http://example.com/4/", "Site 4");
+ webkit_web_back_forward_list_add_item(backForwardList, item4);
+ g_object_unref(item4);
+
+ /* make sure these functions don't add unnecessary ref to the history item */
+ backItem = webkit_web_back_forward_list_get_back_item(backForwardList);
+ g_object_ref(backItem);
+ g_assert_cmpint(G_OBJECT(backItem)->ref_count, ==, 2);
+ g_object_unref(backItem);
+ g_assert_cmpint(G_OBJECT(backItem)->ref_count, ==, 1);
+
+ currentItem = webkit_web_back_forward_list_get_current_item(backForwardList);
+ g_object_ref(currentItem);
+ g_assert_cmpint(G_OBJECT(currentItem)->ref_count, ==, 2);
+ g_object_unref(currentItem);
+ g_assert_cmpint(G_OBJECT(currentItem)->ref_count, ==, 1);
+
+ webkit_web_back_forward_list_go_to_item(backForwardList, item2);
+ forwardItem = webkit_web_back_forward_list_get_forward_item(backForwardList);
+ g_object_ref(forwardItem);
+ g_assert_cmpint(G_OBJECT(forwardItem)->ref_count, ==, 2);
+ g_object_unref(forwardItem);
+ g_assert_cmpint(G_OBJECT(forwardItem)->ref_count, ==, 1);
+
+ nthItem = webkit_web_back_forward_list_get_nth_item(backForwardList, 1);
+ g_object_ref(nthItem);
+ g_assert_cmpint(G_OBJECT(nthItem)->ref_count, ==, 2);
+ g_object_unref(nthItem);
+ g_assert_cmpint(G_OBJECT(nthItem)->ref_count, ==, 1);
+
+ backList = webkit_web_back_forward_list_get_back_list_with_limit(backForwardList, 5);
+ for (; backList; backList = backList->next)
+ g_assert_cmpint(G_OBJECT(backList->data)->ref_count, ==, 1);
+
+ forwardList = webkit_web_back_forward_list_get_forward_list_with_limit(backForwardList, 5);
+ for (; forwardList; forwardList = forwardList->next)
+ g_assert_cmpint(G_OBJECT(forwardList->data)->ref_count, ==, 1);
+
+ g_list_free(forwardList);
+ g_list_free(backList);
+ g_assert_cmpint(G_OBJECT(item1)->ref_count, ==, 1);
+ g_assert_cmpint(G_OBJECT(item2)->ref_count, ==, 1);
+ g_assert_cmpint(G_OBJECT(item3)->ref_count, ==, 1);
+ g_assert_cmpint(G_OBJECT(item4)->ref_count, ==, 1);
+ g_assert_cmpint(G_OBJECT(backForwardList)->ref_count, ==, 1);
+ g_object_unref(webView);
+}
+
+static void test_webkit_web_back_forward_list_order(void)
+{
+ WebKitWebView* webView;
+ WebKitWebBackForwardList* webBackForwardList;
+ WebKitWebHistoryItem* item1;
+ WebKitWebHistoryItem* item2;
+ WebKitWebHistoryItem* item3;
+ WebKitWebHistoryItem* item4;
+ WebKitWebHistoryItem* currentItem;
+ GList* backList = NULL;
+ GList* forwardList = NULL;
+ g_test_bug("22694");
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+
+ webkit_web_view_set_maintains_back_forward_list(webView, TRUE);
+ webBackForwardList = webkit_web_view_get_back_forward_list(webView);
+ g_assert(webBackForwardList);
+
+ // Check that there is no item.
+ g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList));
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+
+ // Add a new items
+ item1 = webkit_web_history_item_new_with_data("http://example.com/1/", "Site 1");
+ webkit_web_back_forward_list_add_item(webBackForwardList, item1);
+ g_object_unref(item1);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item1));
+
+ item2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Site 2");
+ webkit_web_back_forward_list_add_item(webBackForwardList, item2);
+ g_object_unref(item2);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item2));
+
+ item3 = webkit_web_history_item_new_with_data("http://example.com/3/", "Site 3");
+ webkit_web_back_forward_list_add_item(webBackForwardList, item3);
+ g_object_unref(item3);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item3));
+
+ item4 = webkit_web_history_item_new_with_data("http://example.com/4/", "Site 4");
+ webkit_web_back_forward_list_add_item(webBackForwardList, item4);
+ g_object_unref(item4);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, item4));
+
+ // check the back list order
+ backList = webkit_web_back_forward_list_get_back_list_with_limit(webBackForwardList, 5);
+ g_assert(backList);
+
+ currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/3/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 3");
+ backList = backList->next;
+
+ currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 2");
+ backList = backList->next;
+
+ currentItem = WEBKIT_WEB_HISTORY_ITEM(backList->data);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/1/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 1");
+ g_list_free(backList);
+
+ // check the forward list order
+ g_assert(webkit_web_view_go_to_back_forward_item(webView, item1));
+ forwardList = webkit_web_back_forward_list_get_forward_list_with_limit(webBackForwardList,5);
+ g_assert(forwardList);
+
+ currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/4/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 4");
+ forwardList = forwardList->next;
+
+ currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/3/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 3");
+ forwardList = forwardList->next;
+
+ currentItem = WEBKIT_WEB_HISTORY_ITEM(forwardList->data);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Site 2");
+
+ g_list_free(forwardList);
+ g_object_unref(webView);
+}
+
+static void test_webkit_web_back_forward_list_add_item(void)
+{
+ WebKitWebView* webView;
+ WebKitWebBackForwardList* webBackForwardList;
+ WebKitWebHistoryItem* addItem1;
+ WebKitWebHistoryItem* addItem2;
+ WebKitWebHistoryItem* backItem;
+ WebKitWebHistoryItem* currentItem;
+ g_test_bug("22988");
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+
+ webkit_web_view_set_maintains_back_forward_list(webView, TRUE);
+ webBackForwardList = webkit_web_view_get_back_forward_list(webView);
+ g_assert(webBackForwardList);
+
+ // Check that there is no item.
+ g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList));
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+
+ // Add a new item
+ addItem1 = webkit_web_history_item_new_with_data("http://example.com/", "Added site");
+ webkit_web_back_forward_list_add_item(webBackForwardList, addItem1);
+ g_object_unref(addItem1);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem1));
+
+ // Check that the added item is the current item.
+ currentItem = webkit_web_back_forward_list_get_current_item(webBackForwardList);
+ g_assert(currentItem);
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Added site");
+
+ // Add another item.
+ addItem2 = webkit_web_history_item_new_with_data("http://example.com/2/", "Added site 2");
+ webkit_web_back_forward_list_add_item(webBackForwardList, addItem2);
+ g_object_unref(addItem2);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem2));
+
+ // Check that the added item is new current item.
+ currentItem = webkit_web_back_forward_list_get_current_item(webBackForwardList);
+ g_assert(currentItem);
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 1);
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(webkit_web_view_can_go_back(webView));
+ g_assert_cmpstr(webkit_web_history_item_get_uri(currentItem), ==, "http://example.com/2/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(currentItem), ==, "Added site 2");
+
+ backItem = webkit_web_back_forward_list_get_back_item(webBackForwardList);
+ g_assert(backItem);
+ g_assert_cmpstr(webkit_web_history_item_get_uri(backItem), ==, "http://example.com/");
+ g_assert_cmpstr(webkit_web_history_item_get_title(backItem), ==, "Added site");
+
+ // Go to the first added item.
+ g_assert(webkit_web_view_go_to_back_forward_item(webView, addItem1));
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 1);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+
+ g_object_unref(webView);
+}
+
+static void test_webkit_web_back_forward_list_clear(void)
+{
+ WebKitWebView* webView;
+ WebKitWebBackForwardList* webBackForwardList;
+ WebKitWebHistoryItem* addItem;
+ g_test_bug("36173");
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+
+ webBackForwardList = webkit_web_view_get_back_forward_list(webView);
+ g_assert(webBackForwardList);
+
+ // Check that there is no item.
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList));
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+
+ // Check that clearing the empty list does not modify counters
+ webkit_web_back_forward_list_clear(webBackForwardList);
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList));
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+
+ // Add a new item
+ addItem = webkit_web_history_item_new_with_data("http://example.com/", "Added site");
+ webkit_web_back_forward_list_add_item(webBackForwardList, addItem);
+ g_object_unref(addItem);
+ g_assert(webkit_web_back_forward_list_contains_item(webBackForwardList, addItem));
+
+ // Check that after clearing the list the added item is no longer in the list
+ webkit_web_back_forward_list_clear(webBackForwardList);
+ g_assert(!webkit_web_back_forward_list_contains_item(webBackForwardList, addItem));
+
+ // Check that after clearing it, the list is empty
+ g_assert_cmpint(webkit_web_back_forward_list_get_forward_length(webBackForwardList), ==, 0);
+ g_assert_cmpint(webkit_web_back_forward_list_get_back_length(webBackForwardList), ==, 0);
+ g_assert(!webkit_web_back_forward_list_get_current_item(webBackForwardList));
+ g_assert(!webkit_web_view_can_go_forward(webView));
+ g_assert(!webkit_web_view_can_go_back(webView));
+
+ g_object_unref(webView);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/webbackforwardlist/add_item", test_webkit_web_back_forward_list_add_item);
+ g_test_add_func("/webkit/webbackforwardlist/list_order", test_webkit_web_back_forward_list_order);
+ g_test_add_func("/webkit/webhistoryitem/lifetime", test_webkit_web_history_item_lifetime);
+ g_test_add_func("/webkit/webbackforwardlist/clear", test_webkit_web_back_forward_list_clear);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebdatasource.c b/Source/WebKit/gtk/tests/testwebdatasource.c
new file mode 100644
index 0000000..96d95e4
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebdatasource.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2009 Jan Michael Alonzo
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static const gshort defaultTimeout = 10;
+guint waitTimer;
+gboolean shouldWait;
+
+typedef struct {
+ WebKitWebView* webView;
+ WebKitWebFrame* mainFrame;
+} WebDataSourceFixture;
+
+static void test_webkit_web_data_source_get_initial_request()
+{
+ WebKitWebView* view;
+ WebKitWebFrame* frame;
+ WebKitWebDataSource* dataSource;
+ WebKitNetworkRequest* initialRequest;
+
+ view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(view);
+ frame = webkit_web_view_get_main_frame(view);
+
+ WebKitNetworkRequest* request = webkit_network_request_new("http://www.google.com");
+ webkit_web_frame_load_request(frame, request);
+ g_object_unref(request);
+
+ dataSource = webkit_web_frame_get_provisional_data_source(frame);
+ g_assert(dataSource);
+ initialRequest = webkit_web_data_source_get_initial_request(dataSource);
+ g_assert_cmpstr(webkit_network_request_get_uri(initialRequest), ==, "http://www.google.com/");
+
+ g_object_unref(view);
+}
+
+static void notify_load_status_unreachable_cb(WebKitWebView* view, GParamSpec* pspec, GMainLoop* loop)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status (view);
+ WebKitWebFrame* frame = webkit_web_view_get_main_frame(view);
+
+ g_assert(status != WEBKIT_LOAD_FINISHED);
+
+ if (status != WEBKIT_LOAD_FAILED)
+ return;
+
+ WebKitWebDataSource* datasource = webkit_web_frame_get_data_source(frame);
+
+ g_assert_cmpstr("http://this.host.does.not.exist/doireallyexist.html", ==,
+ webkit_web_data_source_get_unreachable_uri(datasource));
+
+ g_main_loop_quit(loop);
+}
+
+static void notify_load_status_cb(WebKitWebView* view, GParamSpec* pspec, GMainLoop* loop)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status (view);
+ WebKitWebFrame* frame = webkit_web_view_get_main_frame(view);
+ WebKitWebDataSource* dataSource = webkit_web_frame_get_data_source(frame);
+
+ if (status == WEBKIT_LOAD_COMMITTED) {
+ g_assert(webkit_web_data_source_is_loading(dataSource));
+ return;
+ }
+ else if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ /* Test get_request */
+ g_test_message("Testing webkit_web_data_source_get_request");
+ WebKitNetworkRequest* request = webkit_web_data_source_get_request(dataSource);
+ g_assert_cmpstr(webkit_network_request_get_uri(request), ==, "http://webkit.org/");
+
+ /* Test get_main_resource */
+ g_test_message("Testing webkit_web_data_source_get_main_resource");
+ WebKitWebResource* resource = webkit_web_data_source_get_main_resource(dataSource);
+ g_assert_cmpstr("text/html", ==, webkit_web_resource_get_mime_type(resource));
+ g_assert_cmpstr("http://webkit.org/", ==, webkit_web_resource_get_uri(resource));
+
+ /* Test get_data. We just test if data has certain size for the mean time */
+ g_test_message("Testing webkit_web_data_source_get_data has certain size");
+ GString* data = webkit_web_data_source_get_data(dataSource);
+ g_assert(data->len > 100);
+
+ /* FIXME: Add test for get_encoding */
+
+ g_main_loop_quit(loop);
+}
+
+static gboolean wait_timer_fired(GMainLoop* loop)
+{
+ waitTimer = 0;
+ g_main_loop_quit(loop);
+
+ return FALSE;
+}
+
+static void test_webkit_web_data_source()
+{
+ WebKitWebView* view;
+ GMainLoop* loop;
+
+ view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(view);
+ loop = g_main_loop_new(NULL, TRUE);
+ g_signal_connect(view, "notify::load-status", G_CALLBACK(notify_load_status_cb), loop);
+ webkit_web_view_load_uri(view, "http://webkit.org");
+
+ waitTimer = g_timeout_add_seconds(defaultTimeout, (GSourceFunc)wait_timer_fired, loop);
+
+ g_main_loop_run(loop);
+
+ if (waitTimer)
+ g_source_remove(waitTimer);
+
+ waitTimer = 0;
+
+ g_main_loop_unref(loop);
+ g_object_unref(view);
+}
+
+static void notify_load_status_lifetime_cb(WebKitWebView* view, GParamSpec* pspec, GMainLoop* loop)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status (view);
+ WebKitWebFrame* frame = webkit_web_view_get_main_frame(view);
+ WebKitWebDataSource* dataSource = webkit_web_frame_get_data_source(frame);
+
+ if (status == WEBKIT_LOAD_COMMITTED) {
+ g_assert(webkit_web_data_source_is_loading(dataSource));
+ return;
+ } else if (status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ g_main_loop_quit(loop);
+}
+
+static void test_webkit_web_data_source_lifetime()
+{
+ WebKitWebView* view;
+ GMainLoop* loop;
+
+ view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(view);
+ loop = g_main_loop_new(NULL, TRUE);
+ g_signal_connect(view, "notify::load-status", G_CALLBACK(notify_load_status_lifetime_cb), loop);
+ webkit_web_view_load_uri(view, "http://webkit.org");
+
+ waitTimer = g_timeout_add_seconds(defaultTimeout, (GSourceFunc)wait_timer_fired, loop);
+
+ g_main_loop_run(loop);
+
+ WebKitWebDataSource* dataSource = webkit_web_frame_get_data_source(webkit_web_view_get_main_frame(view));
+ GList* subResources = webkit_web_data_source_get_subresources(dataSource);
+ gint numberOfResources = g_list_length(subResources);
+ g_list_free(subResources);
+
+ g_assert_cmpint(webkit_web_view_get_load_status(view), ==, WEBKIT_LOAD_FINISHED);
+
+ webkit_web_view_load_uri(view, "http://gnome.org");
+
+ g_assert_cmpint(webkit_web_view_get_load_status(view), ==, WEBKIT_LOAD_PROVISIONAL);
+
+ webkit_web_view_stop_loading(view);
+
+ g_assert_cmpint(webkit_web_view_get_load_status(view), ==, WEBKIT_LOAD_FAILED);
+
+ subResources = webkit_web_data_source_get_subresources(dataSource);
+ g_assert_cmpint(numberOfResources, ==, g_list_length(subResources));
+ g_list_free(subResources);
+
+ if (waitTimer)
+ g_source_remove(waitTimer);
+
+ waitTimer = 0;
+
+ g_main_loop_unref(loop);
+ g_object_unref(view);
+}
+
+static void test_webkit_web_data_source_unreachable_uri()
+{
+ /* FIXME: this test fails currently. */
+ return;
+
+ WebKitWebView* view;
+ GMainLoop* loop;
+
+ view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(view);
+ loop = g_main_loop_new(NULL, TRUE);
+ g_signal_connect(view, "notify::load-status", G_CALLBACK(notify_load_status_unreachable_cb), loop);
+ webkit_web_view_load_uri(view, "http://this.host.does.not.exist/doireallyexist.html");
+
+ waitTimer = g_timeout_add_seconds(defaultTimeout, (GSourceFunc)wait_timer_fired, loop);
+
+ g_main_loop_run(loop);
+
+ if (waitTimer)
+ g_source_remove(waitTimer);
+
+ waitTimer = 0;
+
+ g_main_loop_unref(loop);
+ g_object_unref(view);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_bug("24758");
+ g_test_add_func("/webkit/webdatasource/get_initial_request",
+ test_webkit_web_data_source_get_initial_request);
+ g_test_add_func("/webkit/webdatasource/api",
+ test_webkit_web_data_source);
+ g_test_add_func("/webkit/webdatasource/unreachable_uri",
+ test_webkit_web_data_source_unreachable_uri);
+ g_test_add_func("/webkit/webdatasource/lifetime",
+ test_webkit_web_data_source_lifetime);
+
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebframe.c b/Source/WebKit/gtk/tests/testwebframe.c
new file mode 100644
index 0000000..d1ff7ea
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebframe.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static int numberOfFramesCreated = 0;
+
+static void createFrameSignalTestFrameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* frame, gpointer data)
+{
+ numberOfFramesCreated++;
+}
+
+static gboolean createFrameSignalTestTimeout(gpointer data)
+{
+ g_assert_cmpint(numberOfFramesCreated, ==, 2);
+ g_main_loop_quit((GMainLoop*) data);
+ return FALSE;
+}
+
+static void test_webkit_web_frame_created_signal(void)
+{
+ GtkWidget* webView;
+ GtkWidget* window;
+ GMainLoop* loop = g_main_loop_new(NULL, TRUE);
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ webView = webkit_web_view_new();
+ g_signal_connect(webView, "frame-created", G_CALLBACK(createFrameSignalTestFrameCreatedCallback), loop);
+
+ // We want to ensure that exactly two create-frame signals are
+ // fired and no more, so we set a timeout here. There does not appear
+ // to be a simple way via the API to figure out when all frames have
+ // loaded.
+ g_timeout_add(500, createFrameSignalTestTimeout, loop);
+
+ gtk_container_add(GTK_CONTAINER(window), webView);
+ gtk_widget_show(window);
+ gtk_widget_show(webView);
+
+ webkit_web_view_load_string(WEBKIT_WEB_VIEW(webView),
+ "<html><body>Frames!"
+ "<iframe></iframe>"
+ "<iframe></iframe>"
+ "</body></html>",
+ "text/html", "utf-8", "file://");
+ g_main_loop_run(loop);
+}
+
+static void test_webkit_web_frame_create_destroy(void)
+{
+ GtkWidget *webView;
+ GtkWidget *window;
+
+ g_test_bug("21837");
+ webView = webkit_web_view_new();
+ g_object_ref_sink(webView);
+ g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1);
+ // This crashed with the original version
+ g_object_unref(webView);
+
+ g_test_bug("25042");
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ webView = webkit_web_view_new();
+ gtk_container_add(GTK_CONTAINER(window), webView);
+ gtk_widget_show(window);
+ gtk_widget_show(webView);
+ gtk_widget_destroy(webView);
+}
+
+static void test_webkit_web_frame_lifetime(void)
+{
+ WebKitWebView* webView;
+ WebKitWebFrame* webFrame;
+ g_test_bug("21837");
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1);
+ webFrame = webkit_web_view_get_main_frame(webView);
+ g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1);
+
+ // Add dummy reference on the WebKitWebFrame to keep it alive
+ g_object_ref(webFrame);
+ g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 2);
+
+ // This crashed with the original version
+ g_object_unref(webView);
+
+ // Make sure that the frame got deleted as well. We did this
+ // by adding an extra ref on the WebKitWebFrame and we should
+ // be the one holding the last reference.
+ g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1);
+ g_object_unref(webFrame);
+}
+
+static gboolean print_requested_cb(WebKitWebView* webView, WebKitWebFrame* webFrame, GMainLoop* loop)
+{
+ g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(TRUE));
+ g_main_loop_quit(loop);
+ return TRUE;
+}
+
+static void print_timeout(GMainLoop* loop)
+{
+ if (g_main_loop_is_running(loop))
+ g_main_loop_quit(loop);
+}
+
+static void test_webkit_web_frame_printing(void)
+{
+ WebKitWebView* webView;
+
+ webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(webView);
+ g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1);
+
+ webkit_web_view_load_string(webView,
+ "<html><body><h1>WebKitGTK+!</h1></body></html>",
+ "text/html",
+ "utf-8",
+ "file://");
+
+ GMainLoop* loop = g_main_loop_new(NULL, TRUE);
+
+ // Does javascript print() work correctly?
+ g_signal_connect(webView, "print-requested",
+ G_CALLBACK(print_requested_cb),
+ loop);
+
+ g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(FALSE));
+ webkit_web_view_execute_script (webView, "print();");
+
+ // Give javascriptcore some time to process the print request, but
+ // prepare a timeout to avoid it running forever in case the signal is
+ // never emitted.
+ g_timeout_add(1000, (GSourceFunc)print_timeout, loop);
+ g_main_loop_run(loop);
+
+ g_assert_cmpint(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(webView), "signal-handled")), ==, TRUE);
+
+ // Does printing directly to a file?
+ GError *error = NULL;
+ gchar* temporaryFilename = NULL;
+ gint fd = g_file_open_tmp ("webkit-testwebframe-XXXXXX", &temporaryFilename, &error);
+ close(fd);
+
+ if (error) {
+ g_critical("Failed to open a temporary file for writing: %s.", error->message);
+ g_error_free(error);
+ goto cleanup;
+ }
+
+ // We delete the file, so that we can easily figure out that the
+ // file got printed;
+ if (g_unlink(temporaryFilename) == -1) {
+ g_warning("Failed to delete the temporary file: %s.\nThis may cause the test to be bogus.", g_strerror(errno));
+ }
+
+ WebKitWebFrame* webFrame = webkit_web_view_get_main_frame(webView);
+ GtkPrintOperation* operation = gtk_print_operation_new();
+ GtkPrintOperationAction action = GTK_PRINT_OPERATION_ACTION_EXPORT;
+ GtkPrintOperationResult result;
+
+ gtk_print_operation_set_export_filename(operation, temporaryFilename);
+ result = webkit_web_frame_print_full (webFrame, operation, action, NULL);
+
+ g_assert_cmpint(result, ==, GTK_PRINT_OPERATION_RESULT_APPLY);
+ g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE);
+
+ g_unlink(temporaryFilename);
+ g_object_unref(operation);
+cleanup:
+ g_object_unref(webView);
+ g_free(temporaryFilename);
+}
+
+static void test_webkit_web_frame_response()
+{
+ WebKitWebFrame* frame = g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL);
+ WebKitNetworkResponse* response = webkit_web_frame_get_network_response(frame);
+ g_assert(!response);
+ g_object_unref(frame);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/webview/create_destroy", test_webkit_web_frame_create_destroy);
+ g_test_add_func("/webkit/webview/frame-created_signal", test_webkit_web_frame_created_signal);
+ g_test_add_func("/webkit/webframe/lifetime", test_webkit_web_frame_lifetime);
+ g_test_add_func("/webkit/webview/printing", test_webkit_web_frame_printing);
+ g_test_add_func("/webkit/webview/response", test_webkit_web_frame_response);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebhistoryitem.c b/Source/WebKit/gtk/tests/testwebhistoryitem.c
new file mode 100644
index 0000000..362dc98
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebhistoryitem.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Jan Michael Alonzo
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+typedef struct {
+ WebKitWebHistoryItem* item;
+} WebHistoryItemFixture;
+
+static void web_history_item_fixture_setup(WebHistoryItemFixture* fixture,
+ gconstpointer data)
+{
+ fixture->item = webkit_web_history_item_new_with_data("http://example.com/", "Example1");
+ g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, == , 1);
+ g_assert(fixture->item != NULL);
+}
+
+static void web_history_item_fixture_teardown(WebHistoryItemFixture* fixture,
+ gconstpointer data)
+{
+ g_assert(fixture->item != NULL);
+ g_assert_cmpint(G_OBJECT(fixture->item)->ref_count, ==, 1);
+}
+
+static void test_webkit_web_history_item_get_data(WebHistoryItemFixture* fixture,
+ gconstpointer data)
+{
+ g_assert_cmpstr(webkit_web_history_item_get_title(fixture->item), ==, "Example1");
+ g_assert_cmpstr(webkit_web_history_item_get_uri(fixture->item), ==, "http://example.com/");
+}
+
+static void test_webkit_web_history_item_alternate_title(WebHistoryItemFixture* fixture,
+ gconstpointer data)
+{
+ webkit_web_history_item_set_alternate_title(fixture->item, "Alternate title");
+ g_assert_cmpstr(webkit_web_history_item_get_alternate_title(fixture->item), ==, "Alternate title");
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add("/webkit/webhistoryitem/get_data",
+ WebHistoryItemFixture, 0, web_history_item_fixture_setup,
+ test_webkit_web_history_item_get_data, web_history_item_fixture_teardown);
+ g_test_add("/webkit/webhistoryitem/alternate_title",
+ WebHistoryItemFixture, 0, web_history_item_fixture_setup,
+ test_webkit_web_history_item_alternate_title, web_history_item_fixture_teardown);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebplugindatabase.c b/Source/WebKit/gtk/tests/testwebplugindatabase.c
new file mode 100644
index 0000000..1366f84
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebplugindatabase.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <errno.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+/* This function is not public, so we need an extern declaration */
+extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory);
+
+static void test_webkit_web_plugin_database_get_plugins()
+{
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ WebKitWebPluginDatabase* database;
+ GSList* pluginList, *p;
+ gboolean found = FALSE;
+ gboolean enabled = FALSE;
+
+ webkit_web_settings_add_extra_plugin_directory(view, TEST_PLUGIN_DIR);
+ g_object_ref_sink(G_OBJECT(view));
+
+ database = webkit_get_web_plugin_database();
+ pluginList = webkit_web_plugin_database_get_plugins(database);
+ for (p = pluginList; p; p = p->next) {
+ WebKitWebPlugin* plugin = (WebKitWebPlugin*)p->data;
+ if (!g_strcmp0(webkit_web_plugin_get_name(plugin), "WebKit Test PlugIn") &&
+ !g_strcmp0(webkit_web_plugin_get_description(plugin), "Simple Netscape plug-in that handles test content for WebKit")) {
+ found = TRUE;
+ enabled = webkit_web_plugin_get_enabled(plugin);
+ webkit_web_plugin_set_enabled(plugin, FALSE);
+ }
+ }
+ webkit_web_plugin_database_plugins_list_free(pluginList);
+ g_assert(found);
+ g_assert(enabled);
+
+ webkit_web_plugin_database_refresh(database);
+ pluginList = webkit_web_plugin_database_get_plugins(database);
+
+ for (p = pluginList; p; p = p->next) {
+ WebKitWebPlugin* plugin = (WebKitWebPlugin*)p->data;
+ if (!g_strcmp0(webkit_web_plugin_get_name(plugin), "WebKit Test PlugIn") &&
+ !g_strcmp0(webkit_web_plugin_get_description(plugin), "Simple Netscape plug-in that handles test content for WebKit"))
+ enabled = webkit_web_plugin_get_enabled(plugin);
+ }
+ webkit_web_plugin_database_plugins_list_free(pluginList);
+ g_assert(!enabled);
+
+ g_object_unref(view);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/webplugindatabase/getplugins", test_webkit_web_plugin_database_get_plugins);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need at least gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebresource.c b/Source/WebKit/gtk/tests/testwebresource.c
new file mode 100644
index 0000000..1b893a9
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebresource.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2009 Jan Michael Alonzo
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <libsoup/soup.h>
+#include <string.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+#define INDEX_HTML "<html></html>"
+#define MAIN_HTML "<html><head><script language=\"javascript\" src=\"/javascript.js\"></script></head><body><h1>hah</h1></html>"
+#define JAVASCRIPT "function blah () { var a = 1; }"
+
+GMainLoop* loop;
+SoupSession *session;
+char *base_uri;
+WebKitWebResource* main_resource;
+WebKitWebResource* sub_resource;
+
+typedef struct {
+ WebKitWebResource* webResource;
+ WebKitWebView* webView;
+} WebResourceFixture;
+
+/* For real request testing */
+static void
+server_callback (SoupServer *server, SoupMessage *msg,
+ const char *path, GHashTable *query,
+ SoupClientContext *context, gpointer data)
+{
+ if (msg->method != SOUP_METHOD_GET) {
+ soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ soup_message_set_status (msg, SOUP_STATUS_OK);
+
+ /* Redirect */
+ if (g_str_equal (path, "/")) {
+ soup_message_set_status (msg, SOUP_STATUS_MOVED_PERMANENTLY);
+
+ soup_message_headers_append (msg->response_headers,
+ "Location", "/index.html");
+ } else if (g_str_equal (path, "/index.html")) {
+ soup_message_body_append (msg->response_body,
+ SOUP_MEMORY_COPY,
+ INDEX_HTML,
+ strlen (INDEX_HTML));
+ } else if (g_str_equal (path, "/main.html")) {
+ soup_message_body_append (msg->response_body,
+ SOUP_MEMORY_COPY,
+ MAIN_HTML,
+ strlen (MAIN_HTML));
+ } else if (g_str_equal (path, "/javascript.js")) {
+ soup_message_body_append (msg->response_body,
+ SOUP_MEMORY_COPY,
+ JAVASCRIPT,
+ strlen (JAVASCRIPT));
+ }
+
+
+ soup_message_body_complete (msg->response_body);
+}
+
+static void web_resource_fixture_setup(WebResourceFixture* fixture, gconstpointer data)
+{
+ fixture->webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(fixture->webView);
+ const gchar* webData = "<html></html>";
+ fixture->webResource = webkit_web_resource_new(webData, strlen(webData), "http://example.com/", "text/html", "utf8", "Example.com");
+ g_assert(fixture->webResource);
+}
+
+static void web_resource_fixture_teardown(WebResourceFixture* fixture, gconstpointer data)
+{
+ g_assert(fixture->webResource);
+ g_object_unref(fixture->webResource);
+ g_object_unref(fixture->webView);
+}
+
+static void test_webkit_web_resource_get_url(WebResourceFixture* fixture, gconstpointer data)
+{
+ gchar* url;
+ g_object_get(G_OBJECT(fixture->webResource), "uri", &url, NULL);
+ g_assert_cmpstr(url, ==, "http://example.com/");
+ g_assert_cmpstr(webkit_web_resource_get_uri(fixture->webResource) ,==,"http://example.com/");
+ g_free(url);
+}
+
+static void test_webkit_web_resource_get_data(WebResourceFixture* fixture, gconstpointer data)
+{
+ GString* charData = webkit_web_resource_get_data(fixture->webResource);
+ g_assert_cmpstr(charData->str, ==, "<html></html>");
+}
+
+static void test_webkit_web_resource_get_mime_type(WebResourceFixture* fixture, gconstpointer data)
+{
+ gchar* mime_type;
+ g_object_get(G_OBJECT(fixture->webResource), "mime-type", &mime_type, NULL);
+ g_assert_cmpstr(mime_type, ==, "text/html");
+ g_assert_cmpstr(webkit_web_resource_get_mime_type(fixture->webResource),==,"text/html");
+ g_free(mime_type);
+}
+
+static void test_webkit_web_resource_get_encoding(WebResourceFixture* fixture, gconstpointer data)
+{
+ gchar* text_encoding;
+ g_object_get(G_OBJECT(fixture->webResource), "encoding", &text_encoding, NULL);
+ g_assert_cmpstr(text_encoding, ==, "utf8");
+ g_assert_cmpstr(webkit_web_resource_get_encoding(fixture->webResource),==,"utf8");
+ g_free(text_encoding);
+}
+
+static void test_webkit_web_resource_get_frame_name(WebResourceFixture* fixture, gconstpointer data)
+{
+ gchar* frame_name;
+ g_object_get(G_OBJECT(fixture->webResource), "frame-name", &frame_name, NULL);
+ g_assert_cmpstr(frame_name, ==, "Example.com");
+ g_assert_cmpstr(webkit_web_resource_get_frame_name(fixture->webResource),==,"Example.com");
+ g_free(frame_name);
+}
+
+static void resource_request_starting_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebKitWebResource* web_resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response, gpointer data)
+{
+ gint* been_there = data;
+ *been_there = *been_there + 1;
+
+ if (*been_there == 1) {
+ g_assert(!main_resource);
+ main_resource = g_object_ref(web_resource);
+
+ g_assert_cmpstr(webkit_web_resource_get_uri(web_resource), ==, base_uri);
+
+ /* This should be a redirect, so the response must be NULL */
+ g_assert(!response);
+ } else if (*been_there == 2) {
+ char* uri = g_strdup_printf("%sindex.html", base_uri);
+
+ g_assert_cmpstr(webkit_web_resource_get_uri(web_resource), ==, uri);
+
+ /* Cancel the request. */
+ webkit_network_request_set_uri(request, "about:blank");
+
+ g_free(uri);
+ }
+}
+
+static void notify_load_status_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED) {
+ gboolean* been_there = data;
+ *been_there = TRUE;
+
+ g_assert_cmpstr(webkit_web_view_get_uri(web_view), ==, "about:blank");
+
+ g_main_loop_quit(loop);
+ }
+}
+
+static void test_web_resource_loading()
+{
+ WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ gint been_to_resource_request_starting = 0;
+ gboolean been_to_load_finished = FALSE;
+ WebKitWebFrame* web_frame;
+ WebKitWebDataSource* data_source;
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_ref_sink(web_view);
+
+ g_signal_connect(web_view, "resource-request-starting",
+ G_CALLBACK(resource_request_starting_cb),
+ &been_to_resource_request_starting);
+
+ g_signal_connect(web_view, "notify::load-status",
+ G_CALLBACK(notify_load_status_cb),
+ &been_to_load_finished);
+
+ webkit_web_view_load_uri(web_view, base_uri);
+
+ /* We won't get finished immediately, because of the redirect */
+ g_main_loop_run(loop);
+
+ web_frame = webkit_web_view_get_main_frame(web_view);
+ data_source = webkit_web_frame_get_data_source(web_frame);
+
+ g_assert(main_resource);
+ g_assert(webkit_web_data_source_get_main_resource(data_source) == main_resource);
+ g_object_unref(main_resource);
+
+ g_assert_cmpint(been_to_resource_request_starting, ==, 2);
+ g_assert_cmpint(been_to_load_finished, ==, TRUE);
+
+ g_object_unref(web_view);
+ g_main_loop_unref(loop);
+}
+
+static void resource_request_starting_sub_cb(WebKitWebView* web_view, WebKitWebFrame* web_frame, WebKitWebResource* web_resource, WebKitNetworkRequest* request, WebKitNetworkResponse* response, gpointer data)
+{
+ if (!main_resource)
+ main_resource = g_object_ref(web_resource);
+ else if (!sub_resource)
+ sub_resource = g_object_ref(web_resource);
+}
+
+static void notify_load_status_sub_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED)
+ g_main_loop_quit(loop);
+}
+
+static gboolean idle_quit_loop_cb(gpointer data)
+{
+ g_main_loop_quit(loop);
+ return FALSE;
+}
+
+static void test_web_resource_sub_resource_loading()
+{
+ WebKitWebView* web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ WebKitWebFrame* web_frame;
+ WebKitWebDataSource* data_source;
+ GList* sub_resources;
+ char* uri = g_strdup_printf("%smain.html", base_uri);
+
+ main_resource = NULL;
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_ref_sink(web_view);
+
+ g_signal_connect(web_view, "resource-request-starting",
+ G_CALLBACK(resource_request_starting_sub_cb),
+ NULL);
+
+ g_signal_connect(web_view, "notify::load-status",
+ G_CALLBACK(notify_load_status_sub_cb),
+ NULL);
+
+ webkit_web_view_load_uri(web_view, uri);
+
+ g_main_loop_run(loop);
+
+ /* The main resource should be loaded; now let's wait for the sub-resource to load */
+ g_idle_add(idle_quit_loop_cb, NULL);
+ g_main_loop_run(loop);
+
+ g_assert(main_resource && sub_resource);
+ g_assert(main_resource != sub_resource);
+
+ web_frame = webkit_web_view_get_main_frame(web_view);
+ data_source = webkit_web_frame_get_data_source(web_frame);
+
+ g_assert(webkit_web_data_source_get_main_resource(data_source) == main_resource);
+ g_object_unref(main_resource);
+
+ sub_resources = webkit_web_data_source_get_subresources(data_source);
+ // Expected resources: javascripts.js, favicon.ico
+ g_assert(sub_resources);
+ g_assert(sub_resources->next);
+ g_assert(!sub_resources->next->next);
+
+ // Test that the object we got from the data source is the same
+ // that went through resource-request-starting. Note that the order is
+ // not important (and not guaranteed since the resources are stored in a
+ // hashtable).
+ g_assert(WEBKIT_WEB_RESOURCE(sub_resources->data) == sub_resource
+ || WEBKIT_WEB_RESOURCE(sub_resources->next->data) == sub_resource);
+
+ g_object_unref(web_view);
+ g_main_loop_unref(loop);
+}
+
+int main(int argc, char** argv)
+{
+ SoupServer* server;
+ SoupURI* soup_uri;
+
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
+ soup_server_run_async(server);
+
+ soup_server_add_handler(server, NULL, server_callback, NULL, NULL);
+
+ soup_uri = soup_uri_new("http://127.0.0.1/");
+ soup_uri_set_port(soup_uri, soup_server_get_port(server));
+
+ base_uri = soup_uri_to_string(soup_uri, FALSE);
+ soup_uri_free(soup_uri);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add("/webkit/webresource/get_url",
+ WebResourceFixture, 0, web_resource_fixture_setup,
+ test_webkit_web_resource_get_url, web_resource_fixture_teardown);
+ g_test_add("/webkit/webresource/get_mime_type",
+ WebResourceFixture, 0, web_resource_fixture_setup,
+ test_webkit_web_resource_get_mime_type, web_resource_fixture_teardown);
+ g_test_add("/webkit/webresource/get_text_encoding_name",
+ WebResourceFixture, 0, web_resource_fixture_setup,
+ test_webkit_web_resource_get_encoding, web_resource_fixture_teardown);
+ g_test_add("/webkit/webresource/get_frame_name",
+ WebResourceFixture, 0, web_resource_fixture_setup,
+ test_webkit_web_resource_get_frame_name, web_resource_fixture_teardown);
+ g_test_add("/webkit/webresource/get_data",
+ WebResourceFixture, 0, web_resource_fixture_setup,
+ test_webkit_web_resource_get_data, web_resource_fixture_teardown);
+
+ g_test_add_func("/webkit/webresource/loading", test_web_resource_loading);
+ g_test_add_func("/webkit/webresource/sub_resource_loading", test_web_resource_sub_resource_loading);
+
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebsettings.c b/Source/WebKit/gtk/tests/testwebsettings.c
new file mode 100644
index 0000000..4db929a
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebsettings.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Jan Michael Alonzo
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static void test_webkit_web_settings_user_agent(void)
+{
+ WebKitWebSettings* settings;
+ GtkWidget* webView;
+ gchar* defaultUserAgent;
+ gchar* userAgent;
+ g_test_bug("17375");
+
+ webView = webkit_web_view_new();
+ g_object_ref_sink(webView);
+
+ settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webView));
+ defaultUserAgent = g_strdup(webkit_web_settings_get_user_agent(settings));
+
+ // test a custom UA string
+ userAgent = NULL;
+ g_object_set(G_OBJECT(settings), "user-agent", "testwebsettings/0.1", NULL);
+ g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
+ g_assert_cmpstr(userAgent, ==, "testwebsettings/0.1");
+ g_free(userAgent);
+
+ // setting it to NULL or an empty value should give us the default UA string
+ userAgent = NULL;
+ g_object_set(G_OBJECT(settings), "user-agent", NULL, NULL);
+ g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
+ g_assert_cmpstr(userAgent, ==, defaultUserAgent);
+ g_free(userAgent);
+
+ userAgent = NULL;
+ g_object_set(G_OBJECT(settings), "user-agent", "", NULL);
+ g_object_get(G_OBJECT(settings),"user-agent", &userAgent, NULL);
+ g_assert_cmpstr(userAgent, ==, defaultUserAgent);
+ g_free(userAgent);
+
+ g_free(defaultUserAgent);
+ g_object_unref(webView);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/websettings/user_agent", test_webkit_web_settings_user_agent);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwebview.c b/Source/WebKit/gtk/tests/testwebview.c
new file mode 100644
index 0000000..778235d
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwebview.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ * Copyright (C) 2009, 2010 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "test_utils.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+GMainLoop* loop;
+SoupSession *session;
+char* base_uri;
+
+/* For real request testing */
+static void
+server_callback(SoupServer* server, SoupMessage* msg,
+ const char* path, GHashTable* query,
+ SoupClientContext* context, gpointer data)
+{
+ if (msg->method != SOUP_METHOD_GET) {
+ soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ return;
+ }
+
+ soup_message_set_status(msg, SOUP_STATUS_OK);
+
+ if (g_str_equal(path, "/favicon.ico")) {
+ char* contents;
+ gsize length;
+ GError* error = NULL;
+
+ g_file_get_contents("blank.ico", &contents, &length, &error);
+ g_assert(!error);
+
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, length);
+ } else if (g_str_equal(path, "/bigdiv.html")) {
+ char* contents = g_strdup("<html><body><a id=\"link\" href=\"http://abc.def\">test</a><div style=\"background-color: green; height: 1200px;\"></div></body></html>");
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents));
+ } else if (g_str_equal(path, "/iframe.html")) {
+ char* contents = g_strdup("<html><body id=\"some-content\"><div style=\"background-color: green; height: 50px;\"></div><iframe src=\"bigdiv.html\"></iframe></body></html>");
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents));
+ } else {
+ char* contents = g_strdup("<html><body>test</body></html>");
+ soup_message_body_append(msg->response_body, SOUP_MEMORY_TAKE, contents, strlen(contents));
+ }
+
+ soup_message_body_complete(msg->response_body);
+}
+
+static void idle_quit_loop_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED ||
+ webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FAILED)
+ g_main_loop_quit(loop);
+}
+
+static void icon_uri_changed_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ gboolean* been_here = (gboolean*)data;
+ char* expected_uri;
+
+ g_assert_cmpstr(g_param_spec_get_name(pspec), ==, "icon-uri");
+
+ expected_uri = g_strdup_printf("%sfavicon.ico", base_uri);
+ g_assert_cmpstr(webkit_web_view_get_icon_uri(web_view), ==, expected_uri);
+ g_free(expected_uri);
+
+ *been_here = TRUE;
+}
+
+static void icon_loaded_cb(WebKitWebView* web_view, char* icon_uri, gpointer data)
+{
+ gboolean* been_here = (gboolean*)data;
+ char* expected_uri = g_strdup_printf("%sfavicon.ico", base_uri);
+ g_assert_cmpstr(icon_uri, ==, expected_uri);
+ g_free(expected_uri);
+
+ g_assert_cmpstr(icon_uri, ==, webkit_web_view_get_icon_uri(web_view));
+
+ *been_here = TRUE;
+}
+
+static void test_webkit_web_view_icon_uri()
+{
+ gboolean been_to_uri_changed = FALSE;
+ gboolean been_to_icon_loaded = FALSE;
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ g_object_ref_sink(G_OBJECT(view));
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_connect(G_OBJECT(view),
+ "signal::notify::progress", idle_quit_loop_cb, NULL,
+ "signal::notify::icon-uri", icon_uri_changed_cb, &been_to_uri_changed,
+ "signal::icon-loaded", icon_loaded_cb, &been_to_icon_loaded,
+ NULL);
+
+ webkit_web_view_load_uri(view, base_uri);
+
+ g_main_loop_run(loop);
+
+ g_assert(been_to_uri_changed);
+ g_assert(been_to_icon_loaded);
+
+ g_object_unref(view);
+}
+
+static gboolean map_event_cb(GtkWidget *widget, GdkEvent* event, gpointer data)
+{
+ GMainLoop* loop = (GMainLoop*)data;
+ g_main_loop_quit(loop);
+
+ return FALSE;
+}
+
+static void test_webkit_web_view_grab_focus()
+{
+ char* uri = g_strconcat(base_uri, "iframe.html", NULL);
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
+ GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ GtkAdjustment* adjustment;
+
+ gtk_window_set_default_size(GTK_WINDOW(window), 400, 200);
+
+ gtk_container_add(GTK_CONTAINER(window), scrolled_window);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(view));
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_signal_connect(view, "notify::progress", G_CALLBACK (idle_quit_loop_cb), NULL);
+
+ /* Wait for window to show up */
+ gtk_widget_show_all(window);
+ g_signal_connect(window, "map-event",
+ G_CALLBACK(map_event_cb), loop);
+ g_main_loop_run(loop);
+
+ /* Load a page with a big div that will cause scrollbars to appear */
+ webkit_web_view_load_uri(view, uri);
+ g_main_loop_run(loop);
+
+ adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0);
+
+ /* Since webkit_web_view_execute_script does not return a value,
+ it is impossible to know if an inner document has focus after
+ a node of it was focused via .focus() method.
+ The code below is an workaround: if the node has focus, a scroll
+ action is performed and afterward it is checked if the adjustment
+ has to be different from 0.
+ */
+ char script[] = "var innerDoc = document.defaultView.frames[0].document; \
+ innerDoc.getElementById(\"link\").focus(); \
+ if (innerDoc.hasFocus()) \
+ window.scrollBy(0, 100);";
+
+ /* Focus an element using JavaScript */
+ webkit_web_view_execute_script(view, script);
+
+ /* Make sure the ScrolledWindow noticed the scroll */
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), !=, 0.0);
+
+ g_free(uri);
+ gtk_widget_destroy(window);
+}
+
+static void do_test_webkit_web_view_adjustments(gboolean with_page_cache)
+{
+ char* effective_uri = g_strconcat(base_uri, "bigdiv.html", NULL);
+ char* second_uri = g_strconcat(base_uri, "iframe.html", NULL);
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GtkWidget* scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ GtkAdjustment* adjustment;
+ double lower;
+ double upper;
+
+ if (with_page_cache) {
+ WebKitWebSettings* settings = webkit_web_view_get_settings(view);
+ g_object_set(settings, "enable-page-cache", TRUE, NULL);
+ }
+
+ gtk_window_set_default_size(GTK_WINDOW(window), 400, 200);
+
+ gtk_container_add(GTK_CONTAINER(window), scrolled_window);
+ gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(view));
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_object_connect(G_OBJECT(view),
+ "signal::notify::progress", idle_quit_loop_cb, NULL,
+ NULL);
+
+ /* Wait for window to show up */
+ gtk_widget_show_all(window);
+ g_signal_connect(window, "map-event",
+ G_CALLBACK(map_event_cb), loop);
+ g_main_loop_run(loop);
+
+ /* Load a page with a big div that will cause scrollbars to appear */
+ webkit_web_view_load_uri(view, effective_uri);
+ g_main_loop_run(loop);
+
+ adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0);
+
+ lower = gtk_adjustment_get_lower(adjustment);
+ upper = gtk_adjustment_get_upper(adjustment);
+
+ /* Scroll the view using JavaScript */
+ webkit_web_view_execute_script(view, "window.scrollBy(0, 100)");
+
+ /* Make sure the ScrolledWindow noticed the scroll */
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 100.0);
+
+ /* Load a second URI */
+ webkit_web_view_load_uri(view, second_uri);
+ g_main_loop_run(loop);
+
+ /* Make sure the scrollbar has been reset */
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 0.0);
+
+ /* Go back */
+ webkit_web_view_go_back(view);
+
+ /* When using page cache, go_back will return syncronously */
+ if (!with_page_cache)
+ g_main_loop_run(loop);
+
+ /* Make sure GTK+ has time to process the changes in size, for the adjusments */
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ /* Make sure upper and lower bounds have been restored correctly */
+ g_assert_cmpfloat(lower, ==, gtk_adjustment_get_lower(adjustment));
+ g_assert_cmpfloat(upper, ==, gtk_adjustment_get_upper(adjustment));
+
+ g_assert_cmpfloat(gtk_adjustment_get_value(adjustment), ==, 100.0);
+
+ g_free(effective_uri);
+ g_free(second_uri);
+
+ gtk_widget_destroy(window);
+}
+
+static void test_webkit_web_view_adjustments()
+{
+ /* Test this with page cache disabled, and enabled. */
+ do_test_webkit_web_view_adjustments(FALSE);
+ do_test_webkit_web_view_adjustments(TRUE);
+}
+
+gboolean delayed_destroy(gpointer data)
+{
+ gtk_widget_destroy(GTK_WIDGET(data));
+ g_main_loop_quit(loop);
+ return FALSE;
+}
+
+static void test_webkit_web_view_destroy()
+{
+ GtkWidget* window;
+ GtkWidget* web_view;
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ web_view = webkit_web_view_new();
+
+ gtk_container_add(GTK_CONTAINER(window), web_view);
+
+ gtk_widget_show_all(window);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_signal_connect(window, "map-event",
+ G_CALLBACK(map_event_cb), loop);
+ g_main_loop_run(loop);
+
+ g_idle_add(delayed_destroy, web_view);
+ g_main_loop_run(loop);
+
+ gtk_widget_destroy(window);
+}
+
+static void test_webkit_web_view_window_features()
+{
+ GtkWidget* window;
+ GtkWidget* web_view;
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ web_view = webkit_web_view_new();
+
+ gtk_container_add(GTK_CONTAINER(window), web_view);
+
+ gtk_widget_show_all(window);
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ g_signal_connect(window, "map-event",
+ G_CALLBACK(map_event_cb), loop);
+ g_main_loop_run(loop);
+
+ /* Bug #36144 */
+ g_object_set(G_OBJECT(web_view), "window-features", NULL, NULL);
+
+ gtk_widget_destroy(window);
+}
+
+int main(int argc, char** argv)
+{
+ SoupServer* server;
+ SoupURI* soup_uri;
+
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ /* Hopefully make test independent of the path it's called from. */
+ testutils_relative_chdir("Source/WebKit/gtk/tests/resources/test.html", argv[0]);
+
+ server = soup_server_new(SOUP_SERVER_PORT, 0, NULL);
+ soup_server_run_async(server);
+
+ soup_server_add_handler(server, NULL, server_callback, NULL, NULL);
+
+ soup_uri = soup_uri_new("http://127.0.0.1/");
+ soup_uri_set_port(soup_uri, soup_server_get_port(server));
+
+ base_uri = soup_uri_to_string(soup_uri, FALSE);
+ soup_uri_free(soup_uri);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/webview/icon-uri", test_webkit_web_view_icon_uri);
+ g_test_add_func("/webkit/webview/adjustments", test_webkit_web_view_adjustments);
+ g_test_add_func("/webkit/webview/destroy", test_webkit_web_view_destroy);
+ g_test_add_func("/webkit/webview/grab_focus", test_webkit_web_view_grab_focus);
+ g_test_add_func("/webkit/webview/window-features", test_webkit_web_view_window_features);
+
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif
diff --git a/Source/WebKit/gtk/tests/testwindow.c b/Source/WebKit/gtk/tests/testwindow.c
new file mode 100644
index 0000000..ecd6609
--- /dev/null
+++ b/Source/WebKit/gtk/tests/testwindow.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#if GTK_CHECK_VERSION(2, 14, 0)
+
+static void notify_load_status_cb(WebKitWebView* web_view, GParamSpec* pspec, gpointer data)
+{
+ if (webkit_web_view_get_load_status(web_view) == WEBKIT_LOAD_FINISHED) {
+ GMainLoop* loop = (GMainLoop*)data;
+
+ g_main_loop_quit(loop);
+ }
+}
+
+static void test_webkit_window_scrollbar_policy(void)
+{
+ GMainLoop* loop;
+ GtkWidget* scrolledWindow;
+ GtkWidget* webView;
+ WebKitWebFrame* mainFrame;
+ GtkPolicyType horizontalPolicy;
+ GtkPolicyType verticalPolicy;
+
+ loop = g_main_loop_new(NULL, TRUE);
+
+ scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ webView = webkit_web_view_new();
+ g_object_ref_sink(webView);
+
+ g_signal_connect(webView, "notify::load-status",
+ G_CALLBACK(notify_load_status_cb), loop);
+
+ gtk_container_add(GTK_CONTAINER(scrolledWindow), webView);
+
+ mainFrame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(webView));
+
+ /* Test we correctly apply policy for not having scrollbars; This
+ * case is special, because we turn the policy from NEVER to
+ * AUTOMATIC, since we cannot easily represent the same thing
+ * using GtkScrolledWindow */
+ webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView),
+ "<html><body>WebKit!</body><script>document.getElementsByTagName('body')[0].style.overflow = 'hidden';</script></html>",
+ "file://");
+
+ g_main_loop_run(loop);
+
+ gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(scrolledWindow),
+ &horizontalPolicy, &verticalPolicy);
+
+ g_assert(horizontalPolicy == GTK_POLICY_AUTOMATIC);
+ g_assert(verticalPolicy == GTK_POLICY_AUTOMATIC);
+
+ g_assert(GTK_POLICY_NEVER == webkit_web_frame_get_horizontal_scrollbar_policy(mainFrame));
+ g_assert(GTK_POLICY_NEVER == webkit_web_frame_get_vertical_scrollbar_policy(mainFrame));
+
+ /* Test we correctly apply policy for always having scrollbars */
+ webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView),
+ "<html><body>WebKit!</body><script>document.getElementsByTagName('body')[0].style.overflow = 'scroll';</script></html>",
+ "file://");
+
+ g_main_loop_run(loop);
+
+ gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(scrolledWindow),
+ &horizontalPolicy, &verticalPolicy);
+
+ g_assert(horizontalPolicy == GTK_POLICY_ALWAYS);
+ g_assert(verticalPolicy == GTK_POLICY_ALWAYS);
+
+ g_assert(horizontalPolicy == webkit_web_frame_get_horizontal_scrollbar_policy(mainFrame));
+ g_assert(verticalPolicy == webkit_web_frame_get_vertical_scrollbar_policy(mainFrame));
+
+ /* Test we correctly apply policy for having scrollbars when needed */
+ webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView),
+ "<html><body>WebKit!</body><script>document.getElementsByTagName('body')[0].style.overflow = 'auto';</script></html>",
+ "file://");
+
+ g_main_loop_run(loop);
+
+ gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(scrolledWindow),
+ &horizontalPolicy, &verticalPolicy);
+
+ g_assert(horizontalPolicy == GTK_POLICY_AUTOMATIC);
+ g_assert(verticalPolicy == GTK_POLICY_AUTOMATIC);
+
+ g_assert(horizontalPolicy == webkit_web_frame_get_horizontal_scrollbar_policy(mainFrame));
+ g_assert(verticalPolicy == webkit_web_frame_get_vertical_scrollbar_policy(mainFrame));
+
+ g_object_unref(webView);
+}
+
+int main(int argc, char** argv)
+{
+ g_thread_init(NULL);
+ gtk_test_init(&argc, &argv, NULL);
+
+ g_test_bug_base("https://bugs.webkit.org/");
+ g_test_add_func("/webkit/window/scrollbar_policy", test_webkit_window_scrollbar_policy);
+ return g_test_run ();
+}
+
+#else
+int main(int argc, char** argv)
+{
+ g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
+ return 0;
+}
+
+#endif