/* * Copyright (C) Research In Motion Limited 2010. All rights reserved. * Copyright (C) 2007, 2008 Nikolas Zimmermann * Copyright (C) 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef JSSVGPODListCustom_h #define JSSVGPODListCustom_h #include "JSSVGContextCache.h" #include "JSSVGPODTypeWrapper.h" #include "SVGList.h" namespace WebCore { namespace JSSVGPODListCustom { // Helper structure only containing public typedefs, as C++ does not allow templatized typedefs template struct JSSVGPODListTraits { typedef SVGPODListItem PODListItem; typedef SVGList > PODList; typedef PODType (*ConversionCallback)(JSC::JSValue); }; template static JSC::JSValue finishGetter(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper, PassRefPtr::PODListItem> item) { if (ec) { setDOMException(exec, ec); return JSC::jsUndefined(); } typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); SVGElement* context = JSSVGContextCache::svgContextForDOMObject(wrapper); return toJS(exec, wrapper->globalObject(), JSSVGPODTypeWrapperCreatorForList::create(item.get(), listImp->associatedAttributeName()).get(), context); } template static JSC::JSValue finishSetter(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper, PassRefPtr::PODListItem> item) { if (ec) { setDOMException(exec, ec); return JSC::jsUndefined(); } typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); const QualifiedName& attributeName = listImp->associatedAttributeName(); JSSVGContextCache::propagateSVGDOMChange(wrapper, attributeName); SVGElement* context = JSSVGContextCache::svgContextForDOMObject(wrapper); return toJS(exec, wrapper->globalObject(), JSSVGPODTypeWrapperCreatorForList::create(item.get(), attributeName).get(), context); } template static JSC::JSValue finishSetterReadOnlyResult(JSC::ExecState* exec, ExceptionCode& ec, JSPODListType* wrapper, PassRefPtr::PODListItem> item) { if (ec) { setDOMException(exec, ec); return JSC::jsUndefined(); } typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); JSSVGContextCache::propagateSVGDOMChange(wrapper, listImp->associatedAttributeName()); return toJS(exec, wrapper->globalObject(), JSSVGStaticPODTypeWrapper::create(*item).get(), 0 /* no context on purpose */); } template static JSC::JSValue clear(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback) { ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); listImp->clear(ec); if (ec) setDOMException(exec, ec); else JSSVGContextCache::propagateSVGDOMChange(wrapper, listImp->associatedAttributeName()); return JSC::jsUndefined(); } template static JSC::JSValue initialize(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback conversion) { ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); return finishSetter(exec, ec, wrapper, listImp->initialize(JSSVGPODListTraits::PODListItem::copy(conversion(exec->argument(0))), ec)); } template static JSC::JSValue getItem(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback) { bool indexOk = false; unsigned index = exec->argument(0).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return JSC::jsUndefined(); } ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); return finishGetter(exec, ec, wrapper, listImp->getItem(index, ec)); } template static JSC::JSValue insertItemBefore(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback conversion) { bool indexOk = false; unsigned index = exec->argument(1).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return JSC::jsUndefined(); } ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); return finishSetter(exec, ec, wrapper, listImp->insertItemBefore(JSSVGPODListTraits::PODListItem::copy(conversion(exec->argument(0))), index, ec)); } template static JSC::JSValue replaceItem(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback conversion) { bool indexOk = false; unsigned index = exec->argument(1).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return JSC::jsUndefined(); } ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); return finishSetter(exec, ec, wrapper, listImp->replaceItem(JSSVGPODListTraits::PODListItem::copy(conversion(exec->argument(0))), index, ec)); } template static JSC::JSValue removeItem(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback) { bool indexOk = false; unsigned index = exec->argument(0).toUInt32(exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return JSC::jsUndefined(); } ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); return finishSetterReadOnlyResult(exec, ec, wrapper, listImp->removeItem(index, ec)); } template static JSC::JSValue appendItem(JSPODListType* wrapper, JSC::ExecState* exec, typename JSSVGPODListTraits::ConversionCallback conversion) { ExceptionCode ec = 0; typename JSSVGPODListTraits::PODList* listImp = wrapper->impl(); return finishSetter(exec, ec, wrapper, listImp->appendItem(JSSVGPODListTraits::PODListItem::copy(conversion(exec->argument(0))), ec)); } } } #endif