#pragma once
#include "Element.h"
#include "SVGAttributeOwnerProxy.h"
#include "SVGPropertyTraits.h"
namespace WebCore {
class SVGAttribute { };
template<typename PropertyType>
class SVGPropertyAttribute : public SVGAttribute {
public:
SVGPropertyAttribute()
: m_property(SVGPropertyTraits<PropertyType>::initialValue())
{
}
template<typename... Arguments>
SVGPropertyAttribute(Arguments&&... arguments)
: m_property(std::forward<Arguments>(arguments)...)
{
}
PropertyType& value() { return m_property; }
const PropertyType& value() const { return m_property; }
void setValue(const PropertyType& property) { m_property = property; }
void setValue(PropertyType&& property) { m_property = WTFMove(property); }
void resetValue() { m_property = SVGPropertyTraits<PropertyType>::initialValue(); }
String toString() const { return SVGPropertyTraits<PropertyType>::toString(m_property); }
void setShouldSynchronize(bool shouldSynchronize) { m_shouldSynchronize = shouldSynchronize; }
bool shouldSynchronize() const { return m_shouldSynchronize; }
void synchronize(Element& element, const QualifiedName& attributeName)
{
if (!m_shouldSynchronize)
return;
element.setSynchronizedLazyAttribute(attributeName, toString());
}
protected:
PropertyType m_property;
bool m_shouldSynchronize { false };
};
template<typename TearOffType>
class SVGAnimatedAttribute : public SVGPropertyAttribute<typename TearOffType::ContentType> {
public:
using PropertyTearOffType = TearOffType;
using PropertyType = typename PropertyTearOffType::ContentType;
using Base = SVGPropertyAttribute<PropertyType>;
using Base::m_property;
using Base::m_shouldSynchronize;
SVGAnimatedAttribute() = default;
template<typename... Arguments>
SVGAnimatedAttribute(Arguments&&... arguments)
: Base(std::forward<Arguments>(arguments)...)
{
}
const PropertyType& currentValue(const SVGAttributeOwnerProxy& attributeOwnerProxy) const
{
if (auto wrapper = attributeOwnerProxy.lookupAnimatedProperty(*this)) {
if (wrapper->isAnimating())
return static_pointer_cast<PropertyTearOffType>(wrapper)->currentAnimatedValue();
}
return m_property;
}
RefPtr<PropertyTearOffType> animatedProperty(const SVGAttributeOwnerProxy& attributeOwnerProxy)
{
m_shouldSynchronize = true;
if (auto wrapper = attributeOwnerProxy.lookupOrCreateAnimatedProperty(*this))
return static_pointer_cast<PropertyTearOffType>(wrapper);
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
}
};
template<typename TearOffType>
class SVGAnimatedAttributeList : public SVGAnimatedAttribute<TearOffType> {
public:
using PropertyTearOffType = TearOffType;
using PropertyType = typename PropertyTearOffType::ContentType;
using Base = SVGAnimatedAttribute<PropertyTearOffType>;
SVGAnimatedAttributeList() = default;
template<typename... Arguments>
SVGAnimatedAttributeList(Arguments&&... arguments)
: Base(std::forward<Arguments>(arguments)...)
{
}
void detachAnimatedListWrappers(const SVGAttributeOwnerProxy& attributeOwnerProxy, unsigned newListSize)
{
if (auto wrapper = attributeOwnerProxy.lookupAnimatedProperty(*this))
static_pointer_cast<PropertyTearOffType>(wrapper)->detachListWrappers(newListSize);
}
};
}