Home | History | Annotate | Download | only in js
      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