1/*
2 * This file is part of the WebKit open source project.
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#include "WebKitDOMTreeWalker.h"
22
23#include <WebCore/CSSImportRule.h>
24#include "DOMObjectCache.h"
25#include <WebCore/Document.h>
26#include <WebCore/ExceptionCode.h>
27#include <WebCore/JSExecState.h>
28#include "WebKitDOMNodeFilterPrivate.h"
29#include "WebKitDOMNodePrivate.h"
30#include "WebKitDOMPrivate.h"
31#include "WebKitDOMTreeWalkerPrivate.h"
32#include "ConvertToUTF8String.h"
33#include <wtf/GetPtr.h>
34#include <wtf/RefPtr.h>
35
36#define WEBKIT_DOM_TREE_WALKER_GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE(obj, WEBKIT_DOM_TYPE_TREE_WALKER, WebKitDOMTreeWalkerPrivate)
37
38typedef struct _WebKitDOMTreeWalkerPrivate {
39 RefPtr<WebCore::TreeWalker> coreObject;
40} WebKitDOMTreeWalkerPrivate;
41
42G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
43
44namespace WebKit {
45
46WebKitDOMTreeWalker* kit(WebCore::TreeWalker* obj)
47{
48 if (!obj)
49 return 0;
50
51 if (gpointer ret = DOMObjectCache::get(obj))
52 return WEBKIT_DOM_TREE_WALKER(ret);
53
54 return wrapTreeWalker(obj);
55}
56
57WebCore::TreeWalker* core(WebKitDOMTreeWalker* request)
58{
59 return request ? static_cast<WebCore::TreeWalker*>(WEBKIT_DOM_OBJECT(request)->coreObject) : 0;
60}
61
62WebKitDOMTreeWalker* wrapTreeWalker(WebCore::TreeWalker* coreObject)
63{
64 ASSERT(coreObject);
65 return WEBKIT_DOM_TREE_WALKER(g_object_new(WEBKIT_DOM_TYPE_TREE_WALKER, "core-object", coreObject, nullptr));
66}
67
68} // namespace WebKit
69
70G_DEFINE_TYPE(WebKitDOMTreeWalker, webkit_dom_tree_walker, WEBKIT_DOM_TYPE_OBJECT)
71
72enum {
73 DOM_TREE_WALKER_PROP_0,
74 DOM_TREE_WALKER_PROP_ROOT,
75 DOM_TREE_WALKER_PROP_WHAT_TO_SHOW,
76 DOM_TREE_WALKER_PROP_FILTER,
77 DOM_TREE_WALKER_PROP_CURRENT_NODE,
78};
79
80static void webkit_dom_tree_walker_finalize(GObject* object)
81{
82 WebKitDOMTreeWalkerPrivate* priv = WEBKIT_DOM_TREE_WALKER_GET_PRIVATE(object);
83
84 WebKit::DOMObjectCache::forget(priv->coreObject.get());
85
86 priv->~WebKitDOMTreeWalkerPrivate();
87 G_OBJECT_CLASS(webkit_dom_tree_walker_parent_class)->finalize(object);
88}
89
90static void webkit_dom_tree_walker_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
91{
92 WebKitDOMTreeWalker* self = WEBKIT_DOM_TREE_WALKER(object);
93
94 switch (propertyId) {
95 case DOM_TREE_WALKER_PROP_ROOT:
96 g_value_set_object(value, webkit_dom_tree_walker_get_root(self));
97 break;
98 case DOM_TREE_WALKER_PROP_WHAT_TO_SHOW:
99 g_value_set_ulong(value, webkit_dom_tree_walker_get_what_to_show(self));
100 break;
101 case DOM_TREE_WALKER_PROP_FILTER:
102 g_value_set_object(value, webkit_dom_tree_walker_get_filter(self));
103 break;
104 case DOM_TREE_WALKER_PROP_CURRENT_NODE:
105 g_value_set_object(value, webkit_dom_tree_walker_get_current_node(self));
106 break;
107 default:
108 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
109 break;
110 }
111}
112
113static GObject* webkit_dom_tree_walker_constructor(GType type, guint constructPropertiesCount, GObjectConstructParam* constructProperties)
114{
115 GObject* object = G_OBJECT_CLASS(webkit_dom_tree_walker_parent_class)->constructor(type, constructPropertiesCount, constructProperties);
116
117 WebKitDOMTreeWalkerPrivate* priv = WEBKIT_DOM_TREE_WALKER_GET_PRIVATE(object);
118 priv->coreObject = static_cast<WebCore::TreeWalker*>(WEBKIT_DOM_OBJECT(object)->coreObject);
119 WebKit::DOMObjectCache::put(priv->coreObject.get(), object);
120
121 return object;
122}
123
124static void webkit_dom_tree_walker_class_init(WebKitDOMTreeWalkerClass* requestClass)
125{
126 GObjectClass* gobjectClass = G_OBJECT_CLASS(requestClass);
127 g_type_class_add_private(gobjectClass, sizeof(WebKitDOMTreeWalkerPrivate));
128 gobjectClass->constructor = webkit_dom_tree_walker_constructor;
129 gobjectClass->finalize = webkit_dom_tree_walker_finalize;
130 gobjectClass->get_property = webkit_dom_tree_walker_get_property;
131
132 g_object_class_install_property(
133 gobjectClass,
134 DOM_TREE_WALKER_PROP_ROOT,
135 g_param_spec_object(
136 "root",
137 "TreeWalker:root",
138 "read-only WebKitDOMNode* TreeWalker:root",
139 WEBKIT_DOM_TYPE_NODE,
140 WEBKIT_PARAM_READABLE));
141
142 g_object_class_install_property(
143 gobjectClass,
144 DOM_TREE_WALKER_PROP_WHAT_TO_SHOW,
145 g_param_spec_ulong(
146 "what-to-show",
147 "TreeWalker:what-to-show",
148 "read-only gulong TreeWalker:what-to-show",
149 0, G_MAXULONG, 0,
150 WEBKIT_PARAM_READABLE));
151
152 g_object_class_install_property(
153 gobjectClass,
154 DOM_TREE_WALKER_PROP_FILTER,
155 g_param_spec_object(
156 "filter",
157 "TreeWalker:filter",
158 "read-only WebKitDOMNodeFilter* TreeWalker:filter",
159 WEBKIT_DOM_TYPE_NODE_FILTER,
160 WEBKIT_PARAM_READABLE));
161
162 g_object_class_install_property(
163 gobjectClass,
164 DOM_TREE_WALKER_PROP_CURRENT_NODE,
165 g_param_spec_object(
166 "current-node",
167 "TreeWalker:current-node",
168 "read-only WebKitDOMNode* TreeWalker:current-node",
169 WEBKIT_DOM_TYPE_NODE,
170 WEBKIT_PARAM_READABLE));
171
172}
173
174static void webkit_dom_tree_walker_init(WebKitDOMTreeWalker* request)
175{
176 WebKitDOMTreeWalkerPrivate* priv = WEBKIT_DOM_TREE_WALKER_GET_PRIVATE(request);
177 new (priv) WebKitDOMTreeWalkerPrivate();
178}
179
180WebKitDOMNode* webkit_dom_tree_walker_parent_node(WebKitDOMTreeWalker* self)
181{
182 WebCore::JSMainThreadNullState state;
183 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
184 WebCore::TreeWalker* item = WebKit::core(self);
185
186 auto result = item->parentNode();
187 if (result.hasException())
188 return nullptr;
189
190 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
191 return WebKit::kit(gobjectResult.get());
192}
193
194WebKitDOMNode* webkit_dom_tree_walker_first_child(WebKitDOMTreeWalker* self)
195{
196 WebCore::JSMainThreadNullState state;
197 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
198 WebCore::TreeWalker* item = WebKit::core(self);
199
200 auto result = item->firstChild();
201 if (result.hasException())
202 return nullptr;
203
204 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
205 return WebKit::kit(gobjectResult.get());
206}
207
208WebKitDOMNode* webkit_dom_tree_walker_last_child(WebKitDOMTreeWalker* self)
209{
210 WebCore::JSMainThreadNullState state;
211 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
212 WebCore::TreeWalker* item = WebKit::core(self);
213
214 auto result = item->lastChild();
215 if (result.hasException())
216 return nullptr;
217
218 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
219 return WebKit::kit(gobjectResult.get());
220}
221
222WebKitDOMNode* webkit_dom_tree_walker_previous_sibling(WebKitDOMTreeWalker* self)
223{
224 WebCore::JSMainThreadNullState state;
225 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
226 WebCore::TreeWalker* item = WebKit::core(self);
227
228 auto result = item->previousSibling();
229 if (result.hasException())
230 return nullptr;
231
232 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
233 return WebKit::kit(gobjectResult.get());
234}
235
236WebKitDOMNode* webkit_dom_tree_walker_next_sibling(WebKitDOMTreeWalker* self)
237{
238 WebCore::JSMainThreadNullState state;
239 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
240 WebCore::TreeWalker* item = WebKit::core(self);
241
242 auto result = item->nextSibling();
243 if (result.hasException())
244 return nullptr;
245
246 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
247 return WebKit::kit(gobjectResult.get());
248}
249
250WebKitDOMNode* webkit_dom_tree_walker_previous_node(WebKitDOMTreeWalker* self)
251{
252 WebCore::JSMainThreadNullState state;
253 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
254 WebCore::TreeWalker* item = WebKit::core(self);
255
256 auto result = item->previousNode();
257 if (result.hasException())
258 return nullptr;
259
260 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
261 return WebKit::kit(gobjectResult.get());
262}
263
264WebKitDOMNode* webkit_dom_tree_walker_next_node(WebKitDOMTreeWalker* self)
265{
266 WebCore::JSMainThreadNullState state;
267 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
268 WebCore::TreeWalker* item = WebKit::core(self);
269
270 auto result = item->nextNode();
271 if (result.hasException())
272 return nullptr;
273
274 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(result.releaseReturnValue());
275 return WebKit::kit(gobjectResult.get());
276}
277
278WebKitDOMNode* webkit_dom_tree_walker_get_root(WebKitDOMTreeWalker* self)
279{
280 WebCore::JSMainThreadNullState state;
281 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
282 WebCore::TreeWalker* item = WebKit::core(self);
283 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(item->root());
284 return WebKit::kit(gobjectResult.get());
285}
286
287gulong webkit_dom_tree_walker_get_what_to_show(WebKitDOMTreeWalker* self)
288{
289 WebCore::JSMainThreadNullState state;
290 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
291 WebCore::TreeWalker* item = WebKit::core(self);
292 gulong result = item->whatToShow();
293 return result;
294}
295
296WebKitDOMNodeFilter* webkit_dom_tree_walker_get_filter(WebKitDOMTreeWalker* self)
297{
298 WebCore::JSMainThreadNullState state;
299 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
300 WebCore::TreeWalker* item = WebKit::core(self);
301 RefPtr<WebCore::NodeFilter> gobjectResult = WTF::getPtr(item->filter());
302 return WebKit::kit(gobjectResult.get());
303}
304
305WebKitDOMNode* webkit_dom_tree_walker_get_current_node(WebKitDOMTreeWalker* self)
306{
307 WebCore::JSMainThreadNullState state;
308 g_return_val_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self), 0);
309 WebCore::TreeWalker* item = WebKit::core(self);
310 RefPtr<WebCore::Node> gobjectResult = WTF::getPtr(item->currentNode());
311 return WebKit::kit(gobjectResult.get());
312}
313
314void webkit_dom_tree_walker_set_current_node(WebKitDOMTreeWalker* self, WebKitDOMNode* value, GError** error)
315{
316 WebCore::JSMainThreadNullState state;
317 g_return_if_fail(WEBKIT_DOM_IS_TREE_WALKER(self));
318 g_return_if_fail(WEBKIT_DOM_IS_NODE(value));
319 UNUSED_PARAM(error);
320 WebCore::TreeWalker* item = WebKit::core(self);
321 WebCore::Node* convertedValue = WebKit::core(value);
322 item->setCurrentNode(*convertedValue);
323}
324
325G_GNUC_END_IGNORE_DEPRECATIONS;
326