1/*
2 * Copyright (C) 2013 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21
22#include "WebProcessTest.h"
23#include <gio/gio.h>
24#include <webkit2/webkit-web-extension.h>
25#include <wtf/glib/GUniquePtr.h>
26
27G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
28
29typedef struct _WebKitNodeFilter {
30 GObject parent;
31} WebKitNodeFilter;
32
33typedef struct _WebKitNodeFilterClass {
34 GObjectClass parentClass;
35} WebKitNodeFilterClass;
36
37static short webkitNodeFilterAcceptNode(WebKitDOMNodeFilter*, WebKitDOMNode* node)
38{
39 // Filter out input elements.
40 return WEBKIT_DOM_IS_HTML_INPUT_ELEMENT(node) ? WEBKIT_DOM_NODE_FILTER_REJECT : WEBKIT_DOM_NODE_FILTER_ACCEPT;
41}
42
43static void webkitNodeFilterDOMNodeFilterIfaceInit(WebKitDOMNodeFilterIface* iface)
44{
45 iface->accept_node = webkitNodeFilterAcceptNode;
46}
47
48G_DEFINE_TYPE_WITH_CODE(WebKitNodeFilter, webkit_node_filter, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(WEBKIT_DOM_TYPE_NODE_FILTER, webkitNodeFilterDOMNodeFilterIfaceInit))
49
50static void webkit_node_filter_init(WebKitNodeFilter*)
51{
52}
53
54static void webkit_node_filter_class_init(WebKitNodeFilterClass*)
55{
56}
57
58static const char* expectedNodesAll[] = { "HTML", "HEAD", "TITLE", "#text", "BODY", "INPUT", "INPUT", "BR" };
59static const char* expectedNodesNoInput[] = { "HTML", "HEAD", "TITLE", "#text", "BODY", "BR" };
60static const char* expectedElementsNoInput[] = { "HTML", "HEAD", "TITLE", "BODY", "BR" };
61
62class WebKitDOMNodeFilterTest : public WebProcessTest {
63public:
64 static std::unique_ptr<WebProcessTest> create() { return std::unique_ptr<WebProcessTest>(new WebKitDOMNodeFilterTest()); }
65
66private:
67 bool testTreeWalker(WebKitWebPage* page)
68 {
69 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
70 g_assert_true(WEBKIT_DOM_IS_DOCUMENT(document));
71 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
72
73 WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root");
74 g_assert_true(WEBKIT_DOM_IS_NODE(root));
75 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root));
76
77 // No filter.
78 GRefPtr<WebKitDOMTreeWalker> walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr));
79 g_assert_true(WEBKIT_DOM_IS_TREE_WALKER(walker.get()));
80 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(walker.get()));
81 g_assert_null(webkit_dom_tree_walker_get_filter(walker.get()));
82
83 unsigned i = 0;
84 for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) {
85 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
86 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll));
87 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
88 g_assert_cmpstr(nodeName.get(), ==, expectedNodesAll[i]);
89 }
90 g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesAll));
91
92 // Input elements filter.
93 GRefPtr<WebKitDOMNodeFilter> filter = adoptGRef(static_cast<WebKitDOMNodeFilter*>(g_object_new(webkit_node_filter_get_type(), nullptr)));
94 walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr));
95 g_assert_true(WEBKIT_DOM_IS_TREE_WALKER(walker.get()));
96 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(filter.get()));
97 g_assert_true(webkit_dom_tree_walker_get_filter(walker.get()) == filter.get());
98
99 i = 0;
100 for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) {
101 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
102 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput));
103 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
104 g_assert_cmpstr(nodeName.get(), ==, expectedNodesNoInput[i]);
105 }
106 g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesNoInput));
107
108 // Show only elements, reusing the input filter.
109 walker = adoptGRef(webkit_dom_document_create_tree_walker(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr));
110 g_assert_true(WEBKIT_DOM_IS_TREE_WALKER(walker.get()));
111 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(walker.get()));
112 g_assert_true(webkit_dom_tree_walker_get_filter(walker.get()) == filter.get());
113
114 i = 0;
115 for (WebKitDOMNode* node = WEBKIT_DOM_NODE(root); node; node = webkit_dom_tree_walker_next_node(walker.get()), ++i) {
116 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
117 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput));
118 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
119 g_assert_cmpstr(nodeName.get(), ==, expectedElementsNoInput[i]);
120 }
121 g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedElementsNoInput));
122
123 return true;
124 }
125
126 bool testNodeIterator(WebKitWebPage* page)
127 {
128 WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
129 g_assert_true(WEBKIT_DOM_IS_DOCUMENT(document));
130 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(document));
131
132 WebKitDOMElement* root = webkit_dom_document_get_element_by_id(document, "root");
133 g_assert_true(WEBKIT_DOM_IS_NODE(root));
134 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(root));
135
136 // No filter.
137 GRefPtr<WebKitDOMNodeIterator> iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, nullptr, FALSE, nullptr));
138 g_assert_true(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
139 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
140 g_assert_null(webkit_dom_node_iterator_get_filter(iter.get()));
141
142 unsigned i = 0;
143 while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) {
144 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
145 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesAll));
146 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
147 g_assert_cmpstr(nodeName.get(), ==, expectedNodesAll[i]);
148 i++;
149 }
150 g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesAll));
151
152 // Input elements filter.
153 GRefPtr<WebKitDOMNodeFilter> filter = adoptGRef(static_cast<WebKitDOMNodeFilter*>(g_object_new(webkit_node_filter_get_type(), nullptr)));
154 iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ALL, filter.get(), FALSE, nullptr));
155 g_assert_true(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
156 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
157 g_assert_true(webkit_dom_node_iterator_get_filter(iter.get()) == filter.get());
158
159 i = 0;
160 while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) {
161 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
162 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedNodesNoInput));
163 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
164 g_assert_cmpstr(nodeName.get(), ==, expectedNodesNoInput[i]);
165 i++;
166 }
167 g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedNodesNoInput));
168
169 // Show only elements, reusing the input filter.
170 iter = adoptGRef(webkit_dom_document_create_node_iterator(document, WEBKIT_DOM_NODE(root), WEBKIT_DOM_NODE_FILTER_SHOW_ELEMENT, filter.get(), FALSE, nullptr));
171 g_assert_true(WEBKIT_DOM_IS_NODE_ITERATOR(iter.get()));
172 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(iter.get()));
173 g_assert_true(webkit_dom_node_iterator_get_filter(iter.get()) == filter.get());
174
175 i = 0;
176 while (WebKitDOMNode* node = webkit_dom_node_iterator_next_node(iter.get(), nullptr)) {
177 assertObjectIsDeletedWhenTestFinishes(G_OBJECT(node));
178 g_assert_cmpuint(i, <, G_N_ELEMENTS(expectedElementsNoInput));
179 GUniquePtr<char> nodeName(webkit_dom_node_get_node_name(node));
180 g_assert_cmpstr(nodeName.get(), ==, expectedElementsNoInput[i]);
181 i++;
182 }
183 g_assert_cmpuint(i, ==, G_N_ELEMENTS(expectedElementsNoInput));
184
185 return true;
186 }
187
188 bool runTest(const char* testName, WebKitWebPage* page) override
189 {
190 if (!strcmp(testName, "tree-walker"))
191 return testTreeWalker(page);
192 if (!strcmp(testName, "node-iterator"))
193 return testNodeIterator(page);
194
195 g_assert_not_reached();
196 return false;
197 }
198};
199
200static void __attribute__((constructor)) registerTests()
201{
202 REGISTER_TEST(WebKitDOMNodeFilterTest, "WebKitDOMNodeFilter/tree-walker");
203 REGISTER_TEST(WebKitDOMNodeFilterTest, "WebKitDOMNodeFilter/node-iterator");
204}
205
206G_GNUC_END_IGNORE_DEPRECATIONS;
207