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 "WebKitDOMAttr.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 "WebKitDOMAttrPrivate.h"
30#include "WebKitDOMElementPrivate.h"
31#include "WebKitDOMEventPrivate.h"
32#include "WebKitDOMEventTarget.h"
33#include "WebKitDOMNodePrivate.h"
34#include "WebKitDOMPrivate.h"
35#include "ConvertToUTF8String.h"
36#include <wtf/GetPtr.h>
37#include <wtf/RefPtr.h>
38
39G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
40
41namespace WebKit {
42
43WebKitDOMAttr* kit(WebCore::Attr* obj)
44{
45 return WEBKIT_DOM_ATTR(kit(static_cast<WebCore::Node*>(obj)));
46}
47
48WebCore::Attr* core(WebKitDOMAttr* request)
49{
50 return request ? static_cast<WebCore::Attr*>(WEBKIT_DOM_OBJECT(request)->coreObject) : 0;
51}
52
53WebKitDOMAttr* wrapAttr(WebCore::Attr* coreObject)
54{
55 ASSERT(coreObject);
56 return WEBKIT_DOM_ATTR(g_object_new(WEBKIT_DOM_TYPE_ATTR, "core-object", coreObject, nullptr));
57}
58
59} // namespace WebKit
60
61static gboolean webkit_dom_attr_dispatch_event(WebKitDOMEventTarget* target, WebKitDOMEvent* event, GError** error)
62{
63 WebCore::Event* coreEvent = WebKit::core(event);
64 if (!coreEvent)
65 return false;
66 WebCore::Attr* coreTarget = static_cast<WebCore::Attr*>(WEBKIT_DOM_OBJECT(target)->coreObject);
67
68 auto result = coreTarget->dispatchEventForBindings(*coreEvent);
69 if (result.hasException()) {
70 auto description = WebCore::DOMException::description(result.releaseException().code());
71 g_set_error_literal(error, g_quark_from_string("WEBKIT_DOM"), description.legacyCode, description.name);
72 return false;
73 }
74 return result.releaseReturnValue();
75}
76
77static gboolean webkit_dom_attr_add_event_listener(WebKitDOMEventTarget* target, const char* eventName, GClosure* handler, gboolean useCapture)
78{
79 WebCore::Attr* coreTarget = static_cast<WebCore::Attr*>(WEBKIT_DOM_OBJECT(target)->coreObject);
80 return WebKit::GObjectEventListener::addEventListener(G_OBJECT(target), coreTarget, eventName, handler, useCapture);
81}
82
83static gboolean webkit_dom_attr_remove_event_listener(WebKitDOMEventTarget* target, const char* eventName, GClosure* handler, gboolean useCapture)
84{
85 WebCore::Attr* coreTarget = static_cast<WebCore::Attr*>(WEBKIT_DOM_OBJECT(target)->coreObject);
86 return WebKit::GObjectEventListener::removeEventListener(G_OBJECT(target), coreTarget, eventName, handler, useCapture);
87}
88
89static void webkit_dom_attr_dom_event_target_init(WebKitDOMEventTargetIface* iface)
90{
91 iface->dispatch_event = webkit_dom_attr_dispatch_event;
92 iface->add_event_listener = webkit_dom_attr_add_event_listener;
93 iface->remove_event_listener = webkit_dom_attr_remove_event_listener;
94}
95
96G_DEFINE_TYPE_WITH_CODE(WebKitDOMAttr, webkit_dom_attr, WEBKIT_DOM_TYPE_NODE, G_IMPLEMENT_INTERFACE(WEBKIT_DOM_TYPE_EVENT_TARGET, webkit_dom_attr_dom_event_target_init))
97
98enum {
99 DOM_ATTR_PROP_0,
100 DOM_ATTR_PROP_NAME,
101 DOM_ATTR_PROP_SPECIFIED,
102 DOM_ATTR_PROP_VALUE,
103 DOM_ATTR_PROP_OWNER_ELEMENT,
104 DOM_ATTR_PROP_NAMESPACE_URI,
105 DOM_ATTR_PROP_PREFIX,
106 DOM_ATTR_PROP_LOCAL_NAME,
107};
108
109static void webkit_dom_attr_set_property(GObject* object, guint propertyId, const GValue* value, GParamSpec* pspec)
110{
111 WebKitDOMAttr* self = WEBKIT_DOM_ATTR(object);
112
113 switch (propertyId) {
114 case DOM_ATTR_PROP_VALUE:
115 webkit_dom_attr_set_value(self, g_value_get_string(value), nullptr);
116 break;
117 default:
118 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
119 break;
120 }
121}
122
123static void webkit_dom_attr_get_property(GObject* object, guint propertyId, GValue* value, GParamSpec* pspec)
124{
125 WebKitDOMAttr* self = WEBKIT_DOM_ATTR(object);
126
127 switch (propertyId) {
128 case DOM_ATTR_PROP_NAME:
129 g_value_take_string(value, webkit_dom_attr_get_name(self));
130 break;
131 case DOM_ATTR_PROP_SPECIFIED:
132 g_value_set_boolean(value, webkit_dom_attr_get_specified(self));
133 break;
134 case DOM_ATTR_PROP_VALUE:
135 g_value_take_string(value, webkit_dom_attr_get_value(self));
136 break;
137 case DOM_ATTR_PROP_OWNER_ELEMENT:
138 g_value_set_object(value, webkit_dom_attr_get_owner_element(self));
139 break;
140 case DOM_ATTR_PROP_NAMESPACE_URI:
141 g_value_take_string(value, webkit_dom_attr_get_namespace_uri(self));
142 break;
143 case DOM_ATTR_PROP_PREFIX:
144 g_value_take_string(value, webkit_dom_attr_get_prefix(self));
145 break;
146 case DOM_ATTR_PROP_LOCAL_NAME:
147 g_value_take_string(value, webkit_dom_attr_get_local_name(self));
148 break;
149 default:
150 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propertyId, pspec);
151 break;
152 }
153}
154
155static void webkit_dom_attr_class_init(WebKitDOMAttrClass* requestClass)
156{
157 GObjectClass* gobjectClass = G_OBJECT_CLASS(requestClass);
158 gobjectClass->set_property = webkit_dom_attr_set_property;
159 gobjectClass->get_property = webkit_dom_attr_get_property;
160
161 g_object_class_install_property(
162 gobjectClass,
163 DOM_ATTR_PROP_NAME,
164 g_param_spec_string(
165 "name",
166 "Attr:name",
167 "read-only gchar* Attr:name",
168 "",
169 WEBKIT_PARAM_READABLE));
170
171 g_object_class_install_property(
172 gobjectClass,
173 DOM_ATTR_PROP_SPECIFIED,
174 g_param_spec_boolean(
175 "specified",
176 "Attr:specified",
177 "read-only gboolean Attr:specified",
178 FALSE,
179 WEBKIT_PARAM_READABLE));
180
181 g_object_class_install_property(
182 gobjectClass,
183 DOM_ATTR_PROP_VALUE,
184 g_param_spec_string(
185 "value",
186 "Attr:value",
187 "read-write gchar* Attr:value",
188 "",
189 WEBKIT_PARAM_READWRITE));
190
191 g_object_class_install_property(
192 gobjectClass,
193 DOM_ATTR_PROP_OWNER_ELEMENT,
194 g_param_spec_object(
195 "owner-element",
196 "Attr:owner-element",
197 "read-only WebKitDOMElement* Attr:owner-element",
198 WEBKIT_DOM_TYPE_ELEMENT,
199 WEBKIT_PARAM_READABLE));
200
201 g_object_class_install_property(
202 gobjectClass,
203 DOM_ATTR_PROP_NAMESPACE_URI,
204 g_param_spec_string(
205 "namespace-uri",
206 "Attr:namespace-uri",
207 "read-only gchar* Attr:namespace-uri",
208 "",
209 WEBKIT_PARAM_READABLE));
210
211 g_object_class_install_property(
212 gobjectClass,
213 DOM_ATTR_PROP_PREFIX,
214 g_param_spec_string(
215 "prefix",
216 "Attr:prefix",
217 "read-only gchar* Attr:prefix",
218 "",
219 WEBKIT_PARAM_READABLE));
220
221 g_object_class_install_property(
222 gobjectClass,
223 DOM_ATTR_PROP_LOCAL_NAME,
224 g_param_spec_string(
225 "local-name",
226 "Attr:local-name",
227 "read-only gchar* Attr:local-name",
228 "",
229 WEBKIT_PARAM_READABLE));
230
231}
232
233static void webkit_dom_attr_init(WebKitDOMAttr* request)
234{
235 UNUSED_PARAM(request);
236}
237
238gchar* webkit_dom_attr_get_name(WebKitDOMAttr* self)
239{
240 WebCore::JSMainThreadNullState state;
241 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), 0);
242 WebCore::Attr* item = WebKit::core(self);
243 gchar* result = convertToUTF8String(item->name());
244 return result;
245}
246
247gboolean webkit_dom_attr_get_specified(WebKitDOMAttr* self)
248{
249 WebCore::JSMainThreadNullState state;
250 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), FALSE);
251 WebCore::Attr* item = WebKit::core(self);
252 gboolean result = item->specified();
253 return result;
254}
255
256gchar* webkit_dom_attr_get_value(WebKitDOMAttr* self)
257{
258 WebCore::JSMainThreadNullState state;
259 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), 0);
260 WebCore::Attr* item = WebKit::core(self);
261 gchar* result = convertToUTF8String(item->value());
262 return result;
263}
264
265void webkit_dom_attr_set_value(WebKitDOMAttr* self, const gchar* value, GError** error)
266{
267 WebCore::JSMainThreadNullState state;
268 g_return_if_fail(WEBKIT_DOM_IS_ATTR(self));
269 g_return_if_fail(value);
270 UNUSED_PARAM(error);
271 WebCore::Attr* item = WebKit::core(self);
272 WTF::String convertedValue = WTF::String::fromUTF8(value);
273 item->setValue(convertedValue);
274}
275
276WebKitDOMElement* webkit_dom_attr_get_owner_element(WebKitDOMAttr* self)
277{
278 WebCore::JSMainThreadNullState state;
279 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), 0);
280 WebCore::Attr* item = WebKit::core(self);
281 RefPtr<WebCore::Element> gobjectResult = WTF::getPtr(item->ownerElement());
282 return WebKit::kit(gobjectResult.get());
283}
284
285gchar* webkit_dom_attr_get_namespace_uri(WebKitDOMAttr* self)
286{
287 WebCore::JSMainThreadNullState state;
288 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), 0);
289 WebCore::Attr* item = WebKit::core(self);
290 gchar* result = convertToUTF8String(item->namespaceURI());
291 return result;
292}
293
294gchar* webkit_dom_attr_get_prefix(WebKitDOMAttr* self)
295{
296 WebCore::JSMainThreadNullState state;
297 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), 0);
298 WebCore::Attr* item = WebKit::core(self);
299 gchar* result = convertToUTF8String(item->prefix());
300 return result;
301}
302
303gchar* webkit_dom_attr_get_local_name(WebKitDOMAttr* self)
304{
305 WebCore::JSMainThreadNullState state;
306 g_return_val_if_fail(WEBKIT_DOM_IS_ATTR(self), 0);
307 WebCore::Attr* item = WebKit::core(self);
308 gchar* result = convertToUTF8String(item->localName());
309 return result;
310}
311
312G_GNUC_END_IGNORE_DEPRECATIONS;
313