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 "WebKitDOMDocumentFragment.h"
22
23#include <WebCore/CSSImportRule.h>
24#include "DOMObjectCache.h"
25#include <WebCore/DOMException.h>
26#include <WebCore/Document.h>
27#include "GObjectEventListener.h"
28#include <WebCore/JSExecState.h>
29#include "WebKitDOMDocumentFragmentPrivate.h"
30#include "WebKitDOMElementPrivate.h"
31#include "WebKitDOMEventPrivate.h"
32#include "WebKitDOMEventTarget.h"
33#include "WebKitDOMHTMLCollectionPrivate.h"
34#include "WebKitDOMNodeListPrivate.h"
35#include "WebKitDOMNodePrivate.h"
36#include "WebKitDOMPrivate.h"
37#include "ConvertToUTF8String.h"
38#include "WebKitDOMDocumentFragmentUnstable.h"
39#include <wtf/GetPtr.h>
40#include <wtf/RefPtr.h>
41
42G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
43
44namespace WebKit {
45
46WebKitDOMDocumentFragment* kit(WebCore::DocumentFragment* obj)
47{
48 return WEBKIT_DOM_DOCUMENT_FRAGMENT(kit(static_cast<WebCore::Node*>(obj)));
49}
50
51WebCore::DocumentFragment* core(WebKitDOMDocumentFragment* request)
52{
53 return request ? static_cast<WebCore::DocumentFragment*>(WEBKIT_DOM_OBJECT(request)->coreObject) : 0;
54}
55
56WebKitDOMDocumentFragment* wrapDocumentFragment(WebCore::DocumentFragment* coreObject)
57{
58 ASSERT(coreObject);
59 return WEBKIT_DOM_DOCUMENT_FRAGMENT(g_object_new(WEBKIT_DOM_TYPE_DOCUMENT_FRAGMENT, "core-object", coreObject, nullptr));
60}
61
62} // namespace WebKit
63
64static gboolean webkit_dom_document_fragment_dispatch_event(WebKitDOMEventTarget* target, WebKitDOMEvent* event, GError** error)
65{
66 WebCore::Event* coreEvent = WebKit::core(event);
67 if (!coreEvent)
68 return false;
69 WebCore::DocumentFragment* coreTarget = static_cast<WebCore::DocumentFragment*>(WEBKIT_DOM_OBJECT(target)->coreObject);
70
71 auto result = coreTarget->dispatchEventForBindings(*coreEvent);
72 if (result.hasException()) {
73 auto description = WebCore::DOMException::description(result.releaseException().code());
74 g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), description.legacyCode, description.name);
75 return false;
76 }
77 return result.releaseReturnValue();
78}
79
80static gboolean webkit_dom_document_fragment_add_event_listener(WebKitDOMEventTarget* target, const char* eventName, GClosure* handler, gboolean useCapture)
81{
82 WebCore::DocumentFragment* coreTarget = static_cast<WebCore::DocumentFragment*>(WEBKIT_DOM_OBJECT(target)->coreObject);
83 return WebKit::GObjectEventListener::addEventListener(G_OBJECT(target), coreTarget, eventName, handler, useCapture);
84}
85
86static gboolean webkit_dom_document_fragment_remove_event_listener(WebKitDOMEventTarget* target, const char* eventName, GClosure* handler, gboolean useCapture)
87{
88 WebCore::DocumentFragment* coreTarget = static_cast<WebCore::DocumentFragment*>(WEBKIT_DOM_OBJECT(target)->coreObject);
89 return WebKit::GObjectEventListener::removeEventListener(G_OBJECT(target), coreTarget, eventName, handler, useCapture);
90}
91
92static void webkit_dom_document_fragment_dom_event_target_init(WebKitDOMEventTargetIface* iface)
93{
94 iface->dispatch_event = webkit_dom_document_fragment_dispatch_event;
95 iface->add_event_listener = webkit_dom_document_fragment_add_event_listener;
96 iface->remove_event_listener = webkit_dom_document_fragment_remove_event_listener;
97}
98
99G_DEFINE_TYPE_WITH_CODE(WebKitDOMDocumentFragment, webkit_dom_document_fragment, WEBKIT_DOM_TYPE_NODE, G_IMPLEMENT_INTERFACE(WEBKIT_DOM_TYPE_EVENT_TARGET, webkit_dom_document_fragment_dom_event_target_init))
100
101enum {
102 DOM_DOCUMENT_FRAGMENT_PROP_0,
103 DOM_DOCUMENT_FRAGMENT_PROP_CHILDREN,
104 DOM_DOCUMENT_FRAGMENT_PROP_FIRST_ELEMENT_CHILD,
105 DOM_DOCUMENT_FRAGMENT_PROP_LAST_ELEMENT_CHILD,
106 DOM_DOCUMENT_FRAGMENT_PROP_CHILD_ELEMENT_COUNT,
107};
108
109static void webkit_dom_document_fragment_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
110{
111 WebKitDOMDocumentFragment* self = WEBKIT_DOM_DOCUMENT_FRAGMENT(object);
112
113 switch (propertyId) {
114 case DOM_DOCUMENT_FRAGMENT_PROP_CHILDREN:
115 g_value_set_object(value, webkit_dom_document_fragment_get_children(self));
116 break;
117 case DOM_DOCUMENT_FRAGMENT_PROP_FIRST_ELEMENT_CHILD:
118 g_value_set_object(value, webkit_dom_document_fragment_get_first_element_child(self));
119 break;
120 case DOM_DOCUMENT_FRAGMENT_PROP_LAST_ELEMENT_CHILD:
121 g_value_set_object(value, webkit_dom_document_fragment_get_last_element_child(self));
122 break;
123 case DOM_DOCUMENT_FRAGMENT_PROP_CHILD_ELEMENT_COUNT:
124 g_value_set_ulong(value, webkit_dom_document_fragment_get_child_element_count(self));
125 break;
126 default:
127 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
128 break;
129 }
130}
131
132static void webkit_dom_document_fragment_class_init(WebKitDOMDocumentFragmentClass* requestClass)
133{
134 GObjectClass* gobjectClass = G_OBJECT_CLASS(requestClass);
135 gobjectClass->get_property = webkit_dom_document_fragment_get_property;
136
137 g_object_class_install_property(
138 gobjectClass,
139 DOM_DOCUMENT_FRAGMENT_PROP_CHILDREN,
140 g_param_spec_object(
141 "children",
142 "DocumentFragment:children",
143 "read-only WebKitDOMHTMLCollection* DocumentFragment:children",
144 WEBKIT_DOM_TYPE_HTML_COLLECTION,
145 WEBKIT_PARAM_READABLE));
146
147 g_object_class_install_property(
148 gobjectClass,
149 DOM_DOCUMENT_FRAGMENT_PROP_FIRST_ELEMENT_CHILD,
150 g_param_spec_object(
151 "first-element-child",
152 "DocumentFragment:first-element-child",
153 "read-only WebKitDOMElement* DocumentFragment:first-element-child",
154 WEBKIT_DOM_TYPE_ELEMENT,
155 WEBKIT_PARAM_READABLE));
156
157 g_object_class_install_property(
158 gobjectClass,
159 DOM_DOCUMENT_FRAGMENT_PROP_LAST_ELEMENT_CHILD,
160 g_param_spec_object(
161 "last-element-child",
162 "DocumentFragment:last-element-child",
163 "read-only WebKitDOMElement* DocumentFragment:last-element-child",
164 WEBKIT_DOM_TYPE_ELEMENT,
165 WEBKIT_PARAM_READABLE));
166
167 g_object_class_install_property(
168 gobjectClass,
169 DOM_DOCUMENT_FRAGMENT_PROP_CHILD_ELEMENT_COUNT,
170 g_param_spec_ulong(
171 "child-element-count",
172 "DocumentFragment:child-element-count",
173 "read-only gulong DocumentFragment:child-element-count",
174 0, G_MAXULONG, 0,
175 WEBKIT_PARAM_READABLE));
176
177}
178
179static void webkit_dom_document_fragment_init(WebKitDOMDocumentFragment* request)
180{
181 UNUSED_PARAM(request);
182}
183
184WebKitDOMElement* webkit_dom_document_fragment_get_element_by_id(WebKitDOMDocumentFragment* self, const gchar* elementId)
185{
186 WebCore::JSMainThreadNullState state;
187 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
188 g_return_val_if_fail(elementId, 0);
189 WebCore::DocumentFragment* item = WebKit::core(self);
190 WTF::String convertedElementId = WTF::String::fromUTF8(elementId);
191 RefPtr<WebCore::Element> gobjectResult = WTF::getPtr(item->getElementById(convertedElementId));
192 return WebKit::kit(gobjectResult.get());
193}
194
195WebKitDOMElement* webkit_dom_document_fragment_query_selector(WebKitDOMDocumentFragment* self, const gchar* selectors, GError** error)
196{
197 WebCore::JSMainThreadNullState state;
198 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
199 g_return_val_if_fail(selectors, 0);
200 g_return_val_if_fail(!error || !*error, 0);
201 WebCore::DocumentFragment* item = WebKit::core(self);
202 WTF::String convertedSelectors = WTF::String::fromUTF8(selectors);
203 auto result = item->querySelector(convertedSelectors);
204 if (result.hasException()) {
205 auto description = WebCore::DOMException::description(result.releaseException().code());
206 g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), description.legacyCode, description.name);
207 return nullptr;
208 }
209 return WebKit::kit(result.releaseReturnValue());
210}
211
212WebKitDOMNodeList* webkit_dom_document_fragment_query_selector_all(WebKitDOMDocumentFragment* self, const gchar* selectors, GError** error)
213{
214 WebCore::JSMainThreadNullState state;
215 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
216 g_return_val_if_fail(selectors, 0);
217 g_return_val_if_fail(!error || !*error, 0);
218 WebCore::DocumentFragment* item = WebKit::core(self);
219 WTF::String convertedSelectors = WTF::String::fromUTF8(selectors);
220 auto result = item->querySelectorAll(convertedSelectors);
221 if (result.hasException()) {
222 auto description = WebCore::DOMException::description(result.releaseException().code());
223 g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), description.legacyCode, description.name);
224 return nullptr;
225 }
226 return WebKit::kit(result.releaseReturnValue().ptr());
227}
228
229WebKitDOMHTMLCollection* webkit_dom_document_fragment_get_children(WebKitDOMDocumentFragment* self)
230{
231 WebCore::JSMainThreadNullState state;
232 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
233 WebCore::DocumentFragment* item = WebKit::core(self);
234 RefPtr<WebCore::HTMLCollection> gobjectResult = WTF::getPtr(item->children());
235 return WebKit::kit(gobjectResult.get());
236}
237
238WebKitDOMElement* webkit_dom_document_fragment_get_first_element_child(WebKitDOMDocumentFragment* self)
239{
240 WebCore::JSMainThreadNullState state;
241 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
242 WebCore::DocumentFragment* item = WebKit::core(self);
243 RefPtr<WebCore::Element> gobjectResult = WTF::getPtr(item->firstElementChild());
244 return WebKit::kit(gobjectResult.get());
245}
246
247WebKitDOMElement* webkit_dom_document_fragment_get_last_element_child(WebKitDOMDocumentFragment* self)
248{
249 WebCore::JSMainThreadNullState state;
250 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
251 WebCore::DocumentFragment* item = WebKit::core(self);
252 RefPtr<WebCore::Element> gobjectResult = WTF::getPtr(item->lastElementChild());
253 return WebKit::kit(gobjectResult.get());
254}
255
256gulong webkit_dom_document_fragment_get_child_element_count(WebKitDOMDocumentFragment* self)
257{
258 WebCore::JSMainThreadNullState state;
259 g_return_val_if_fail(WEBKIT_DOM_IS_DOCUMENT_FRAGMENT(self), 0);
260 WebCore::DocumentFragment* item = WebKit::core(self);
261 gulong result = item->childElementCount();
262 return result;
263}
264
265G_GNUC_END_IGNORE_DEPRECATIONS;
266