blob: d60c92da87b1aeb66f18fc4176bffe4f6a191f89 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef StringKeyframe_h
#define StringKeyframe_h
#include "core/animation/Keyframe.h"
#include "core/css/StylePropertySet.h"
#include "wtf/HashMap.h"
namespace blink {
class StyleSheetContents;
// A specialization of Keyframe that associates user specified keyframe
// properties with either CSS properties or SVG attributes.
class StringKeyframe : public Keyframe {
public:
static PassRefPtr<StringKeyframe> create() {
return adoptRef(new StringKeyframe);
}
MutableStylePropertySet::SetResult setCSSPropertyValue(
const AtomicString& propertyName,
const PropertyRegistry*,
const String& value,
StyleSheetContents*);
MutableStylePropertySet::SetResult setCSSPropertyValue(CSSPropertyID,
const String& value,
StyleSheetContents*);
void setCSSPropertyValue(CSSPropertyID, const CSSValue&);
void setPresentationAttributeValue(CSSPropertyID,
const String& value,
StyleSheetContents*);
void setSVGAttributeValue(const QualifiedName&, const String& value);
const CSSValue& cssPropertyValue(const PropertyHandle& property) const {
int index = -1;
if (property.isCSSCustomProperty())
index =
m_cssPropertyMap->findPropertyIndex(property.customPropertyName());
else
index = m_cssPropertyMap->findPropertyIndex(property.cssProperty());
CHECK_GE(index, 0);
return m_cssPropertyMap->propertyAt(static_cast<unsigned>(index)).value();
}
const CSSValue& presentationAttributeValue(CSSPropertyID property) const {
int index = m_presentationAttributeMap->findPropertyIndex(property);
CHECK_GE(index, 0);
return m_presentationAttributeMap->propertyAt(static_cast<unsigned>(index))
.value();
}
String svgPropertyValue(const QualifiedName& attributeName) const {
return m_svgAttributeMap.get(&attributeName);
}
PropertyHandleSet properties() const override;
class CSSPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
public:
static PassRefPtr<CSSPropertySpecificKeyframe> create(
double offset,
PassRefPtr<TimingFunction> easing,
const CSSValue* value,
EffectModel::CompositeOperation composite) {
return adoptRef(new CSSPropertySpecificKeyframe(offset, std::move(easing),
value, composite));
}
const CSSValue* value() const { return m_value.get(); }
bool populateAnimatableValue(CSSPropertyID,
Element&,
const ComputedStyle& baseStyle,
const ComputedStyle* parentStyle) const final;
PassRefPtr<AnimatableValue> getAnimatableValue() const final {
return m_animatableValueCache.get();
}
bool isNeutral() const final { return !m_value; }
PassRefPtr<Keyframe::PropertySpecificKeyframe> neutralKeyframe(
double offset,
PassRefPtr<TimingFunction> easing) const final;
private:
CSSPropertySpecificKeyframe(double offset,
PassRefPtr<TimingFunction> easing,
const CSSValue* value,
EffectModel::CompositeOperation composite)
: Keyframe::PropertySpecificKeyframe(offset,
std::move(easing),
composite),
m_value(const_cast<CSSValue*>(value)) {}
virtual PassRefPtr<Keyframe::PropertySpecificKeyframe> cloneWithOffset(
double offset) const;
bool isCSSPropertySpecificKeyframe() const override { return true; }
// TODO(sashab): Make this a const CSSValue.
Persistent<CSSValue> m_value;
mutable RefPtr<AnimatableValue> m_animatableValueCache;
};
class SVGPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
public:
static PassRefPtr<SVGPropertySpecificKeyframe> create(
double offset,
PassRefPtr<TimingFunction> easing,
const String& value,
EffectModel::CompositeOperation composite) {
return adoptRef(new SVGPropertySpecificKeyframe(offset, std::move(easing),
value, composite));
}
const String& value() const { return m_value; }
PassRefPtr<PropertySpecificKeyframe> cloneWithOffset(
double offset) const final;
PassRefPtr<AnimatableValue> getAnimatableValue() const final {
return nullptr;
}
bool isNeutral() const final { return m_value.isNull(); }
PassRefPtr<PropertySpecificKeyframe> neutralKeyframe(
double offset,
PassRefPtr<TimingFunction> easing) const final;
private:
SVGPropertySpecificKeyframe(double offset,
PassRefPtr<TimingFunction> easing,
const String& value,
EffectModel::CompositeOperation composite)
: Keyframe::PropertySpecificKeyframe(offset,
std::move(easing),
composite),
m_value(value) {}
bool isSVGPropertySpecificKeyframe() const override { return true; }
String m_value;
};
private:
StringKeyframe()
: m_cssPropertyMap(MutableStylePropertySet::create(HTMLStandardMode)),
m_presentationAttributeMap(
MutableStylePropertySet::create(HTMLStandardMode)) {}
StringKeyframe(const StringKeyframe& copyFrom);
PassRefPtr<Keyframe> clone() const override;
PassRefPtr<Keyframe::PropertySpecificKeyframe> createPropertySpecificKeyframe(
PropertyHandle) const override;
bool isStringKeyframe() const override { return true; }
Persistent<MutableStylePropertySet> m_cssPropertyMap;
Persistent<MutableStylePropertySet> m_presentationAttributeMap;
HashMap<const QualifiedName*, String> m_svgAttributeMap;
};
using CSSPropertySpecificKeyframe = StringKeyframe::CSSPropertySpecificKeyframe;
using SVGPropertySpecificKeyframe = StringKeyframe::SVGPropertySpecificKeyframe;
DEFINE_TYPE_CASTS(StringKeyframe,
Keyframe,
value,
value->isStringKeyframe(),
value.isStringKeyframe());
DEFINE_TYPE_CASTS(CSSPropertySpecificKeyframe,
Keyframe::PropertySpecificKeyframe,
value,
value->isCSSPropertySpecificKeyframe(),
value.isCSSPropertySpecificKeyframe());
DEFINE_TYPE_CASTS(SVGPropertySpecificKeyframe,
Keyframe::PropertySpecificKeyframe,
value,
value->isSVGPropertySpecificKeyframe(),
value.isSVGPropertySpecificKeyframe());
} // namespace blink
#endif