91cbbc96ea2244604b6f739b6a2d35b36a162ddc
[WebKit-https.git] / Source / WebKit / WebProcess / InjectedBundle / API / gtk / DOM / WebKitDOMXPathResult.cpp
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 "WebKitDOMXPathResult.h"
22
23 #include <WebCore/CSSImportRule.h>
24 #include "DOMObjectCache.h"
25 #include <WebCore/Document.h>
26 #include <WebCore/ExceptionCode.h>
27 #include <WebCore/ExceptionCodeDescription.h>
28 #include <WebCore/JSMainThreadExecState.h>
29 #include "WebKitDOMNodePrivate.h"
30 #include "WebKitDOMPrivate.h"
31 #include "WebKitDOMXPathResultPrivate.h"
32 #include "ConvertToUTF8String.h"
33 #include <wtf/GetPtr.h>
34 #include <wtf/RefPtr.h>
35
36 #define WEBKIT_DOM_XPATH_RESULT_GET_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE(obj, WEBKIT_DOM_TYPE_XPATH_RESULT, WebKitDOMXPathResultPrivate)
37
38 typedef struct _WebKitDOMXPathResultPrivate {
39     RefPtr<WebCore::XPathResult> coreObject;
40 } WebKitDOMXPathResultPrivate;
41
42 namespace WebKit {
43
44 WebKitDOMXPathResult* kit(WebCore::XPathResult* obj)
45 {
46     if (!obj)
47         return 0;
48
49     if (gpointer ret = DOMObjectCache::get(obj))
50         return WEBKIT_DOM_XPATH_RESULT(ret);
51
52     return wrapXPathResult(obj);
53 }
54
55 WebCore::XPathResult* core(WebKitDOMXPathResult* request)
56 {
57     return request ? static_cast<WebCore::XPathResult*>(WEBKIT_DOM_OBJECT(request)->coreObject) : 0;
58 }
59
60 WebKitDOMXPathResult* wrapXPathResult(WebCore::XPathResult* coreObject)
61 {
62     ASSERT(coreObject);
63     return WEBKIT_DOM_XPATH_RESULT(g_object_new(WEBKIT_DOM_TYPE_XPATH_RESULT, "core-object", coreObject, nullptr));
64 }
65
66 } // namespace WebKit
67
68 G_DEFINE_TYPE(WebKitDOMXPathResult, webkit_dom_xpath_result, WEBKIT_DOM_TYPE_OBJECT)
69
70 enum {
71     PROP_0,
72     PROP_RESULT_TYPE,
73     PROP_NUMBER_VALUE,
74     PROP_STRING_VALUE,
75     PROP_BOOLEAN_VALUE,
76     PROP_SINGLE_NODE_VALUE,
77     PROP_INVALID_ITERATOR_STATE,
78     PROP_SNAPSHOT_LENGTH,
79 };
80
81 static void webkit_dom_xpath_result_finalize(GObject* object)
82 {
83     WebKitDOMXPathResultPrivate* priv = WEBKIT_DOM_XPATH_RESULT_GET_PRIVATE(object);
84
85     WebKit::DOMObjectCache::forget(priv->coreObject.get());
86
87     priv->~WebKitDOMXPathResultPrivate();
88     G_OBJECT_CLASS(webkit_dom_xpath_result_parent_class)->finalize(object);
89 }
90
91 static void webkit_dom_xpath_result_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
92 {
93     WebKitDOMXPathResult* self = WEBKIT_DOM_XPATH_RESULT(object);
94
95     switch (propertyId) {
96     case PROP_RESULT_TYPE:
97         g_value_set_uint(value, webkit_dom_xpath_result_get_result_type(self));
98         break;
99     case PROP_NUMBER_VALUE:
100         g_value_set_double(value, webkit_dom_xpath_result_get_number_value(self, nullptr));
101         break;
102     case PROP_STRING_VALUE:
103         g_value_take_string(value, webkit_dom_xpath_result_get_string_value(self, nullptr));
104         break;
105     case PROP_BOOLEAN_VALUE:
106         g_value_set_boolean(value, webkit_dom_xpath_result_get_boolean_value(self, nullptr));
107         break;
108     case PROP_SINGLE_NODE_VALUE:
109         g_value_set_object(value, webkit_dom_xpath_result_get_single_node_value(self, nullptr));
110         break;
111     case PROP_INVALID_ITERATOR_STATE:
112         g_value_set_boolean(value, webkit_dom_xpath_result_get_invalid_iterator_state(self));
113         break;
114     case PROP_SNAPSHOT_LENGTH:
115         g_value_set_ulong(value, webkit_dom_xpath_result_get_snapshot_length(self, nullptr));
116         break;
117     default:
118         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
119         break;
120     }
121 }
122
123 static GObject* webkit_dom_xpath_result_constructor(GType type, guint constructPropertiesCount, GObjectConstructParam* constructProperties)
124 {
125     GObject* object = G_OBJECT_CLASS(webkit_dom_xpath_result_parent_class)->constructor(type, constructPropertiesCount, constructProperties);
126
127     WebKitDOMXPathResultPrivate* priv = WEBKIT_DOM_XPATH_RESULT_GET_PRIVATE(object);
128     priv->coreObject = static_cast<WebCore::XPathResult*>(WEBKIT_DOM_OBJECT(object)->coreObject);
129     WebKit::DOMObjectCache::put(priv->coreObject.get(), object);
130
131     return object;
132 }
133
134 static void webkit_dom_xpath_result_class_init(WebKitDOMXPathResultClass* requestClass)
135 {
136     GObjectClass* gobjectClass = G_OBJECT_CLASS(requestClass);
137     g_type_class_add_private(gobjectClass, sizeof(WebKitDOMXPathResultPrivate));
138     gobjectClass->constructor = webkit_dom_xpath_result_constructor;
139     gobjectClass->finalize = webkit_dom_xpath_result_finalize;
140     gobjectClass->get_property = webkit_dom_xpath_result_get_property;
141
142     g_object_class_install_property(
143         gobjectClass,
144         PROP_RESULT_TYPE,
145         g_param_spec_uint(
146             "result-type",
147             "XPathResult:result-type",
148             "read-only gushort XPathResult:result-type",
149             0, G_MAXUINT, 0,
150             WEBKIT_PARAM_READABLE));
151
152     g_object_class_install_property(
153         gobjectClass,
154         PROP_NUMBER_VALUE,
155         g_param_spec_double(
156             "number-value",
157             "XPathResult:number-value",
158             "read-only gdouble XPathResult:number-value",
159             -G_MAXDOUBLE, G_MAXDOUBLE, 0,
160             WEBKIT_PARAM_READABLE));
161
162     g_object_class_install_property(
163         gobjectClass,
164         PROP_STRING_VALUE,
165         g_param_spec_string(
166             "string-value",
167             "XPathResult:string-value",
168             "read-only gchar* XPathResult:string-value",
169             "",
170             WEBKIT_PARAM_READABLE));
171
172     g_object_class_install_property(
173         gobjectClass,
174         PROP_BOOLEAN_VALUE,
175         g_param_spec_boolean(
176             "boolean-value",
177             "XPathResult:boolean-value",
178             "read-only gboolean XPathResult:boolean-value",
179             FALSE,
180             WEBKIT_PARAM_READABLE));
181
182     g_object_class_install_property(
183         gobjectClass,
184         PROP_SINGLE_NODE_VALUE,
185         g_param_spec_object(
186             "single-node-value",
187             "XPathResult:single-node-value",
188             "read-only WebKitDOMNode* XPathResult:single-node-value",
189             WEBKIT_DOM_TYPE_NODE,
190             WEBKIT_PARAM_READABLE));
191
192     g_object_class_install_property(
193         gobjectClass,
194         PROP_INVALID_ITERATOR_STATE,
195         g_param_spec_boolean(
196             "invalid-iterator-state",
197             "XPathResult:invalid-iterator-state",
198             "read-only gboolean XPathResult:invalid-iterator-state",
199             FALSE,
200             WEBKIT_PARAM_READABLE));
201
202     g_object_class_install_property(
203         gobjectClass,
204         PROP_SNAPSHOT_LENGTH,
205         g_param_spec_ulong(
206             "snapshot-length",
207             "XPathResult:snapshot-length",
208             "read-only gulong XPathResult:snapshot-length",
209             0, G_MAXULONG, 0,
210             WEBKIT_PARAM_READABLE));
211
212 }
213
214 static void webkit_dom_xpath_result_init(WebKitDOMXPathResult* request)
215 {
216     WebKitDOMXPathResultPrivate* priv = WEBKIT_DOM_XPATH_RESULT_GET_PRIVATE(request);
217     new (priv) WebKitDOMXPathResultPrivate();
218 }
219
220 WebKitDOMNode* webkit_dom_xpath_result_iterate_next(WebKitDOMXPathResult* self, GError** error)
221 {
222     WebCore::JSMainThreadNullState state;
223     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
224     g_return_val_if_fail(!error || !*error, 0);
225     WebCore::XPathResult* item = WebKit::core(self);
226     auto result = item->iterateNext();
227     if (result.hasException()) {
228         WebCore::ExceptionCodeDescription ecdesc(result.releaseException().code());
229         g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
230         return nullptr;
231     }
232     return WebKit::kit(result.releaseReturnValue());
233 }
234
235 WebKitDOMNode* webkit_dom_xpath_result_snapshot_item(WebKitDOMXPathResult* self, gulong index, GError** error)
236 {
237     WebCore::JSMainThreadNullState state;
238     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
239     g_return_val_if_fail(!error || !*error, 0);
240     WebCore::XPathResult* item = WebKit::core(self);
241     auto result = item->snapshotItem(index);
242     if (result.hasException()) {
243         WebCore::ExceptionCodeDescription ecdesc(result.releaseException().code());
244         g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
245         return nullptr;
246     }
247     return WebKit::kit(result.releaseReturnValue());
248 }
249
250 gushort webkit_dom_xpath_result_get_result_type(WebKitDOMXPathResult* self)
251 {
252     WebCore::JSMainThreadNullState state;
253     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
254     WebCore::XPathResult* item = WebKit::core(self);
255     gushort result = item->resultType();
256     return result;
257 }
258
259 gdouble webkit_dom_xpath_result_get_number_value(WebKitDOMXPathResult* self, GError** error)
260 {
261     WebCore::JSMainThreadNullState state;
262     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
263     g_return_val_if_fail(!error || !*error, 0);
264     WebCore::XPathResult* item = WebKit::core(self);
265     auto result = item->numberValue();
266     if (result.hasException()) {
267         WebCore::ExceptionCodeDescription ecdesc(result.releaseException().code());
268         g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
269         return 0;
270     }
271     return result.releaseReturnValue();
272 }
273
274 gchar* webkit_dom_xpath_result_get_string_value(WebKitDOMXPathResult* self, GError** error)
275 {
276     WebCore::JSMainThreadNullState state;
277     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
278     g_return_val_if_fail(!error || !*error, 0);
279     WebCore::XPathResult* item = WebKit::core(self);
280     auto result = item->stringValue();
281     if (result.hasException())
282         return nullptr;
283     return convertToUTF8String(result.releaseReturnValue());
284 }
285
286 gboolean webkit_dom_xpath_result_get_boolean_value(WebKitDOMXPathResult* self, GError** error)
287 {
288     WebCore::JSMainThreadNullState state;
289     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), FALSE);
290     g_return_val_if_fail(!error || !*error, FALSE);
291     WebCore::XPathResult* item = WebKit::core(self);
292     auto result = item->booleanValue();
293     if (result.hasException()) {
294         WebCore::ExceptionCodeDescription ecdesc(result.releaseException().code());
295         g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
296         return false;
297     }
298     return result.releaseReturnValue();
299 }
300
301 WebKitDOMNode* webkit_dom_xpath_result_get_single_node_value(WebKitDOMXPathResult* self, GError** error)
302 {
303     WebCore::JSMainThreadNullState state;
304     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
305     g_return_val_if_fail(!error || !*error, 0);
306     WebCore::XPathResult* item = WebKit::core(self);
307     auto result = item->singleNodeValue();
308     if (result.hasException()) {
309         WebCore::ExceptionCodeDescription ecdesc(result.releaseException().code());
310         g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
311         return nullptr;
312     }
313     return WebKit::kit(result.releaseReturnValue());
314 }
315
316 gboolean webkit_dom_xpath_result_get_invalid_iterator_state(WebKitDOMXPathResult* self)
317 {
318     WebCore::JSMainThreadNullState state;
319     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), FALSE);
320     WebCore::XPathResult* item = WebKit::core(self);
321     gboolean result = item->invalidIteratorState();
322     return result;
323 }
324
325 gulong webkit_dom_xpath_result_get_snapshot_length(WebKitDOMXPathResult* self, GError** error)
326 {
327     WebCore::JSMainThreadNullState state;
328     g_return_val_if_fail(WEBKIT_DOM_IS_XPATH_RESULT(self), 0);
329     g_return_val_if_fail(!error || !*error, 0);
330     WebCore::XPathResult* item = WebKit::core(self);
331     auto result = item->snapshotLength();
332     if (result.hasException()) {
333         WebCore::ExceptionCodeDescription ecdesc(result.releaseException().code());
334         g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), ecdesc.code, ecdesc.name);
335     }
336     return result.releaseReturnValue();
337 }
338