SVGPropertyOwnerRegistry.h [plain text]
#pragma once
#include "SVGAnimatedPropertyAccessorImpl.h"
#include "SVGAnimatedPropertyPairAccessorImpl.h"
#include "SVGPropertyAccessorImpl.h"
#include "SVGPropertyRegistry.h"
#include <wtf/HashMap.h>
namespace WebCore {
class SVGAttributeAnimator;
template<typename OwnerType, typename... BaseTypes>
class SVGPropertyOwnerRegistry : public SVGPropertyRegistry {
public:
SVGPropertyOwnerRegistry(OwnerType& owner)
: m_owner(owner)
{
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGStringList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGStringListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGTransformList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGTransformListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedBoolean> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedBooleanAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, typename EnumType, Ref<SVGAnimatedEnumeration> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedEnumerationAccessor<OwnerType, EnumType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedInteger> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedIntegerAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedLength> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedLengthAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedLengthList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedLengthListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedNumber> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedNumberAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedNumberList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedNumberListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedAngle> OwnerType::*property1, Ref<SVGAnimatedOrientType> OwnerType::*property2>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedAngleOrientAccessor<OwnerType>::template singleton<property1, property2>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedPathSegList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedPathSegListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedPointList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedPointListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedPreserveAspectRatio> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedPreserveAspectRatioAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedRect> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedRectAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedString> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedStringAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedTransformList> OwnerType::*property>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedTransformListAccessor<OwnerType>::template singleton<property>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedInteger> OwnerType::*property1, Ref<SVGAnimatedInteger> OwnerType::*property2>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedIntegerPairAccessor<OwnerType>::template singleton<property1, property2>());
}
template<const LazyNeverDestroyed<const QualifiedName>& attributeName, Ref<SVGAnimatedNumber> OwnerType::*property1, Ref<SVGAnimatedNumber> OwnerType::*property2>
static void registerProperty()
{
registerProperty(attributeName, SVGAnimatedNumberPairAccessor<OwnerType>::template singleton<property1, property2>());
}
template<typename Functor>
static bool enumerateRecursively(const Functor& functor)
{
for (const auto& entry : attributeNameToAccessorMap()) {
if (!functor(entry))
return false;
}
return enumerateRecursivelyBaseTypes(functor);
}
static bool isKnownAttribute(const QualifiedName& attributeName)
{
return findAccessor(attributeName);
}
static bool isAnimatedLengthAttribute(const QualifiedName& attributeName)
{
if (const auto* accessor = findAccessor(attributeName))
return accessor->isAnimatedLength();
return false;
}
QualifiedName propertyAttributeName(const SVGProperty& property) const override
{
QualifiedName attributeName = nullQName();
enumerateRecursively([&](const auto& entry) -> bool {
if (!entry.value->matches(m_owner, property))
return true;
attributeName = entry.key;
return false;
});
return attributeName;
}
QualifiedName animatedPropertyAttributeName(const SVGAnimatedProperty& animatedProperty) const override
{
QualifiedName attributeName = nullQName();
enumerateRecursively([&](const auto& entry) -> bool {
if (!entry.value->matches(m_owner, animatedProperty))
return true;
attributeName = entry.key;
return false;
});
return attributeName;
}
void setAnimatedPropertDirty(const QualifiedName& attributeName, SVGAnimatedProperty& animatedProperty) const override
{
enumerateRecursively([&](const auto& entry) -> bool {
if (!entry.key.matches(attributeName))
return true;
entry.value->setDirty(m_owner, animatedProperty);
return false;
});
}
void detachAllProperties() const override
{
enumerateRecursively([&](const auto& entry) -> bool {
entry.value->detach(m_owner);
return true;
});
}
Optional<String> synchronize(const QualifiedName& attributeName) const override
{
Optional<String> value;
enumerateRecursively([&](const auto& entry) -> bool {
if (!entry.key.matches(attributeName))
return true;
value = entry.value->synchronize(m_owner);
return false;
});
return value;
}
HashMap<QualifiedName, String> synchronizeAllAttributes() const override
{
HashMap<QualifiedName, String> map;
enumerateRecursively([&](const auto& entry) -> bool {
if (auto string = entry.value->synchronize(m_owner))
map.add(entry.key, *string);
return true;
});
return map;
}
bool isAnimatedPropertyAttribute(const QualifiedName& attributeName) const override
{
bool isAnimatedPropertyAttribute = false;
enumerateRecursively([&attributeName, &isAnimatedPropertyAttribute](const auto& entry) -> bool {
if (!entry.key.matches(attributeName))
return true;
isAnimatedPropertyAttribute = entry.value->isAnimatedProperty();
return false;
});
return isAnimatedPropertyAttribute;
}
bool isAnimatedStylePropertyAttribute(const QualifiedName& attributeName) const override
{
static NeverDestroyed<HashSet<QualifiedName::QualifiedNameImpl*>> animatedStyleAttributes = std::initializer_list<QualifiedName::QualifiedNameImpl*> {
SVGNames::cxAttr->impl(),
SVGNames::cyAttr->impl(),
SVGNames::rAttr->impl(),
SVGNames::rxAttr->impl(),
SVGNames::ryAttr->impl(),
SVGNames::heightAttr->impl(),
SVGNames::widthAttr->impl(),
SVGNames::xAttr->impl(),
SVGNames::yAttr->impl()
};
return isAnimatedLengthAttribute(attributeName) && animatedStyleAttributes.get().contains(attributeName.impl());
}
RefPtr<SVGAttributeAnimator> createAnimator(const QualifiedName& attributeName, AnimationMode animationMode, CalcMode calcMode, bool isAccumulated, bool isAdditive) const override
{
RefPtr<SVGAttributeAnimator> animator;
enumerateRecursively([&](const auto& entry) -> bool {
if (!entry.key.matches(attributeName))
return true;
animator = entry.value->createAnimator(m_owner, attributeName, animationMode, calcMode, isAccumulated, isAdditive);
return false;
});
return animator;
}
void appendAnimatedInstance(const QualifiedName& attributeName, SVGAttributeAnimator& animator) const override
{
enumerateRecursively([&](const auto& entry) -> bool {
if (!entry.key.matches(attributeName))
return true;
entry.value->appendAnimatedInstance(m_owner, animator);
return false;
});
}
private:
static HashMap<QualifiedName, const SVGMemberAccessor<OwnerType>*>& attributeNameToAccessorMap()
{
static NeverDestroyed<HashMap<QualifiedName, const SVGMemberAccessor<OwnerType>*>> attributeNameToAccessorMap;
return attributeNameToAccessorMap;
}
static void registerProperty(const QualifiedName& attributeName, const SVGMemberAccessor<OwnerType>& propertyAccessor)
{
attributeNameToAccessorMap().add(attributeName, &propertyAccessor);
}
template<typename Functor, size_t I = 0>
static typename std::enable_if<I == sizeof...(BaseTypes), bool>::type enumerateRecursivelyBaseTypes(const Functor&) { return true; }
template<typename Functor, size_t I = 0>
static typename std::enable_if<I < sizeof...(BaseTypes), bool>::type enumerateRecursivelyBaseTypes(const Functor& functor)
{
using BaseType = typename std::tuple_element<I, typename std::tuple<BaseTypes...>>::type;
if (!BaseType::PropertyRegistry::enumerateRecursively(functor))
return false;
return enumerateRecursivelyBaseTypes<Functor, I + 1>(functor);
}
static const SVGMemberAccessor<OwnerType>* findAccessor(const QualifiedName& attributeName)
{
auto it = std::find_if(attributeNameToAccessorMap().begin(), attributeNameToAccessorMap().end(), [&attributeName](const auto& entry) -> bool {
return entry.key.matches(attributeName);
});
return it != attributeNameToAccessorMap().end() ? it->value : nullptr;
}
OwnerType& m_owner;
};
}