1 /*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3 * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
4 * Copyright (C) 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #ifndef JSSVGPODListCustom_h
23 #define JSSVGPODListCustom_h
24
25 #include "JSSVGContextCache.h"
26 #include "JSSVGPODTypeWrapper.h"
27 #include "SVGList.h"
28
29 namespace WebCore {
30
31 namespace JSSVGPODListCustom {
32
33 // Helper structure only containing public typedefs, as C++ does not allow templatized typedefs
34 template<typename PODType>
35 struct JSSVGPODListTraits {
36 typedef SVGPODListItem<PODType> PODListItem;
37 typedef SVGList<RefPtr<PODListItem> > PODList;
38 typedef PODType (*ConversionCallback)(JSC::JSValue);
39 };
40
41 template<typename JSPODListType, typename PODType>
finishGetter(JSC::ExecState * exec,ExceptionCode & ec,JSPODListType * wrapper,PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item)42 static JSC::JSValue finishGetter(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper,
43 PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item)
44 {
45 if (ec) {
46 setDOMException(exec, ec);
47 return JSC::jsUndefined();
48 }
49
50 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
51
52 SVGElement* context = JSSVGContextCache::svgContextForDOMObject(wrapper);
53 return toJS(exec, wrapper->globalObject(),
54 JSSVGPODTypeWrapperCreatorForList<PODType>::create(item.get(), listImp->associatedAttributeName()).get(), context);
55 }
56
57 template<typename JSPODListType, typename PODType>
finishSetter(JSC::ExecState * exec,ExceptionCode & ec,JSPODListType * wrapper,PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item)58 static JSC::JSValue finishSetter(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper,
59 PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item)
60 {
61 if (ec) {
62 setDOMException(exec, ec);
63 return JSC::jsUndefined();
64 }
65
66 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
67
68 const QualifiedName& attributeName = listImp->associatedAttributeName();
69 JSSVGContextCache::propagateSVGDOMChange(wrapper, attributeName);
70
71 SVGElement* context = JSSVGContextCache::svgContextForDOMObject(wrapper);
72 return toJS(exec, wrapper->globalObject(),
73 JSSVGPODTypeWrapperCreatorForList<PODType>::create(item.get(), attributeName).get(), context);
74 }
75
76 template<typename JSPODListType, typename PODType>
finishSetterReadOnlyResult(JSC::ExecState * exec,ExceptionCode & ec,JSPODListType * wrapper,PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item)77 static JSC::JSValue finishSetterReadOnlyResult(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper,
78 PassRefPtr<typename JSSVGPODListTraits<PODType>::PODListItem> item)
79 {
80 if (ec) {
81 setDOMException(exec, ec);
82 return JSC::jsUndefined();
83 }
84
85 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
86 JSSVGContextCache::propagateSVGDOMChange(wrapper, listImp->associatedAttributeName());
87 return toJS(exec, wrapper->globalObject(),
88 JSSVGStaticPODTypeWrapper<PODType>::create(*item).get(), 0 /* no context on purpose */);
89 }
90
91 template<typename JSPODListType, typename PODType>
clear(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList &,typename JSSVGPODListTraits<PODType>::ConversionCallback)92 static JSC::JSValue clear(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList&,
93 typename JSSVGPODListTraits<PODType>::ConversionCallback)
94 {
95 ExceptionCode ec = 0;
96 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
97 listImp->clear(ec);
98
99 if (ec)
100 setDOMException(exec, ec);
101 else
102 JSSVGContextCache::propagateSVGDOMChange(wrapper, listImp->associatedAttributeName());
103
104 return JSC::jsUndefined();
105 }
106
107 template<typename JSPODListType, typename PODType>
initialize(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList & args,typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)108 static JSC::JSValue initialize(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args,
109 typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)
110 {
111 ExceptionCode ec = 0;
112 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
113 return finishSetter<JSPODListType, PODType>(exec, ec, wrapper,
114 listImp->initialize(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), ec));
115 }
116
117 template<typename JSPODListType, typename PODType>
getItem(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList & args,typename JSSVGPODListTraits<PODType>::ConversionCallback)118 static JSC::JSValue getItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args,
119 typename JSSVGPODListTraits<PODType>::ConversionCallback)
120 {
121 bool indexOk = false;
122 unsigned index = args.at(0).toUInt32(exec, indexOk);
123 if (!indexOk) {
124 setDOMException(exec, TYPE_MISMATCH_ERR);
125 return JSC::jsUndefined();
126 }
127
128 ExceptionCode ec = 0;
129 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
130 return finishGetter<JSPODListType, PODType>(exec, ec, wrapper,
131 listImp->getItem(index, ec));
132 }
133
134 template<typename JSPODListType, typename PODType>
insertItemBefore(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList & args,typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)135 static JSC::JSValue insertItemBefore(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args,
136 typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)
137 {
138 bool indexOk = false;
139 unsigned index = args.at(1).toUInt32(exec, indexOk);
140 if (!indexOk) {
141 setDOMException(exec, TYPE_MISMATCH_ERR);
142 return JSC::jsUndefined();
143 }
144
145 ExceptionCode ec = 0;
146 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
147 return finishSetter<JSPODListType, PODType>(exec, ec, wrapper,
148 listImp->insertItemBefore(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), index, ec));
149 }
150
151 template<typename JSPODListType, typename PODType>
replaceItem(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList & args,typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)152 static JSC::JSValue replaceItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args,
153 typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)
154 {
155 bool indexOk = false;
156 unsigned index = args.at(1).toUInt32(exec, indexOk);
157 if (!indexOk) {
158 setDOMException(exec, TYPE_MISMATCH_ERR);
159 return JSC::jsUndefined();
160 }
161
162 ExceptionCode ec = 0;
163 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
164 return finishSetter<JSPODListType, PODType>(exec, ec, wrapper,
165 listImp->replaceItem(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), index, ec));
166 }
167
168 template<typename JSPODListType, typename PODType>
removeItem(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList & args,typename JSSVGPODListTraits<PODType>::ConversionCallback)169 static JSC::JSValue removeItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args,
170 typename JSSVGPODListTraits<PODType>::ConversionCallback)
171 {
172 bool indexOk = false;
173 unsigned index = args.at(0).toUInt32(exec, indexOk);
174 if (!indexOk) {
175 setDOMException(exec, TYPE_MISMATCH_ERR);
176 return JSC::jsUndefined();
177 }
178
179 ExceptionCode ec = 0;
180 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
181 return finishSetterReadOnlyResult<JSPODListType, PODType>(exec, ec, wrapper,
182 listImp->removeItem(index, ec));
183 }
184
185 template<typename JSPODListType, typename PODType>
appendItem(JSPODListType * wrapper,JSC::ExecState * exec,const JSC::ArgList & args,typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)186 static JSC::JSValue appendItem(JSPODListType* wrapper, JSC::ExecState* exec, const JSC::ArgList& args,
187 typename JSSVGPODListTraits<PODType>::ConversionCallback conversion)
188 {
189 ExceptionCode ec = 0;
190 typename JSSVGPODListTraits<PODType>::PODList* listImp = wrapper->impl();
191 return finishSetter<JSPODListType, PODType>(exec, ec, wrapper,
192 listImp->appendItem(JSSVGPODListTraits<PODType>::PODListItem::copy(conversion(args.at(0))), ec));
193 }
194
195 }
196
197 }
198
199 #endif
200