1 /* 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 3 * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann (at) 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> 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> 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> 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> 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> 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> 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> 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> 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> 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> 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