SVGListPropertyTearOff.h [plain text]
#ifndef SVGListPropertyTearOff_h
#define SVGListPropertyTearOff_h
#if ENABLE(SVG)
#include "SVGListProperty.h"
namespace WebCore {
template<typename PropertyType>
class SVGListPropertyTearOff : public SVGListProperty<PropertyType> {
public:
typedef SVGListProperty<PropertyType> Base;
typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
typedef PassRefPtr<ListItemTearOff> PassListItemTearOff;
typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff;
typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache;
static PassRefPtr<SVGListPropertyTearOff<PropertyType> > create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role)
{
ASSERT(animatedProperty);
return adoptRef(new SVGListPropertyTearOff<PropertyType>(animatedProperty, role));
}
int removeItemFromList(ListItemTearOff* removeItem, bool shouldSynchronizeWrappers)
{
PropertyType& values = m_animatedProperty->values();
ListWrapperCache& wrappers = m_animatedProperty->wrappers();
unsigned size = wrappers.size();
ASSERT(size == values.size());
for (unsigned i = 0; i < size; ++i) {
RefPtr<ListItemTearOff>& item = wrappers.at(i);
if (item != removeItem)
continue;
item->detachWrapper();
wrappers.remove(i);
values.remove(i);
if (shouldSynchronizeWrappers)
commitChange();
return i;
}
return -1;
}
void clear(ExceptionCode& ec)
{
Base::clearValuesAndWrappers(m_animatedProperty.get(), ec);
}
unsigned numberOfItems() const
{
return Base::numberOfItemsValuesAndWrappers(m_animatedProperty.get());
}
PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionCode& ec)
{
return Base::initializeValuesAndWrappers(m_animatedProperty.get(), passNewItem, ec);
}
PassListItemTearOff getItem(unsigned index, ExceptionCode& ec)
{
return Base::getItemValuesAndWrappers(m_animatedProperty.get(), index, ec);
}
PassListItemTearOff insertItemBefore(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec)
{
return Base::insertItemBeforeValuesAndWrappers(m_animatedProperty.get(), passNewItem, index, ec);
}
PassListItemTearOff replaceItem(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec)
{
return Base::replaceItemValuesAndWrappers(m_animatedProperty.get(), passNewItem, index, ec);
}
PassListItemTearOff removeItem(unsigned index, ExceptionCode& ec)
{
return Base::removeItemValuesAndWrappers(m_animatedProperty.get(), index, ec);
}
PassListItemTearOff appendItem(PassListItemTearOff passNewItem, ExceptionCode& ec)
{
return Base::appendItemValuesAndWrappers(m_animatedProperty.get(), passNewItem, ec);
}
protected:
SVGListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role)
: SVGListProperty<PropertyType>(role)
, m_animatedProperty(animatedProperty)
{
}
virtual void commitChange()
{
PropertyType& values = m_animatedProperty->values();
ListWrapperCache& wrappers = m_animatedProperty->wrappers();
unsigned size = wrappers.size();
ASSERT(size == values.size());
for (unsigned i = 0; i < size; ++i) {
RefPtr<ListItemTearOff>& item = wrappers.at(i);
if (!item)
continue;
item->setAnimatedProperty(m_animatedProperty.get());
item->setValue(values.at(i));
}
m_animatedProperty->commitChange();
}
virtual void processIncomingListItemValue(const ListItemType&, unsigned*)
{
ASSERT_NOT_REACHED();
}
virtual void processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify)
{
SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty();
if (!animatedPropertyOfItem)
return;
if (!animatedPropertyOfItem->isAnimatedListTearOff()) {
newItem = ListItemTearOff::create(newItem->propertyReference());
return;
}
bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty;
int removedIndex = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList);
ASSERT(removedIndex != -1);
if (!indexToModify)
return;
if (!livesInOtherList) {
unsigned& index = *indexToModify;
if (static_cast<unsigned>(removedIndex) < index)
--index;
}
}
RefPtr<AnimatedListPropertyTearOff> m_animatedProperty;
};
}
#endif // ENABLE(SVG)
#endif // SVGListPropertyTearOff_h