blob: 90f7cdb90fa626f0ae37a00616b703a62ba6b58f [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/CSSPropertyValueSet.h"
#include "platform/wtf/HashMap.h"
namespace blink {
class StyleSheetContents;
// An implementation of Keyframe used for CSS Animations, web-animations, and
// the HTML <marquee> element.
//
// A StringKeyframe instance supports an arbitrary number of (property, value)
// pairs. The properties can be CSS properties or SVG attributes, mapping to
// CSSValue or plain String values respectively. CSS properties added to a
// StringKeyframe are expanded to shorthand and de-duplicated, with newer
// properties replacing older ones. SVG attributes are similarly de-duplicated.
//
// TODO(smcgruer): By the spec, a StringKeyframe should not de-duplicate or
// expand shorthand properties; that is done for computed keyframes.
class CORE_EXPORT StringKeyframe : public Keyframe {
public:
static scoped_refptr<StringKeyframe> Create() {
return base::AdoptRef(new StringKeyframe);
}
MutableCSSPropertyValueSet::SetResult SetCSSPropertyValue(
const AtomicString& property_name,
const PropertyRegistry*,
const String& value,
SecureContextMode,
StyleSheetContents*);
MutableCSSPropertyValueSet::SetResult SetCSSPropertyValue(
CSSPropertyID,
const String& value,
SecureContextMode,
StyleSheetContents*);
void SetCSSPropertyValue(CSSPropertyID, const CSSValue&);
void SetPresentationAttributeValue(CSSPropertyID,
const String& value,
SecureContextMode,
StyleSheetContents*);
void SetSVGAttributeValue(const QualifiedName&, const String& value);
const CSSValue& CssPropertyValue(const PropertyHandle& property) const {
int index = -1;
if (property.IsCSSCustomProperty())
index =
css_property_map_->FindPropertyIndex(property.CustomPropertyName());
else
index = css_property_map_->FindPropertyIndex(
property.GetCSSProperty().PropertyID());
CHECK_GE(index, 0);
return css_property_map_->PropertyAt(static_cast<unsigned>(index)).Value();
}
const CSSValue& PresentationAttributeValue(CSSPropertyID property) const {
int index = presentation_attribute_map_->FindPropertyIndex(property);
CHECK_GE(index, 0);
return presentation_attribute_map_->PropertyAt(static_cast<unsigned>(index))
.Value();
}
String SvgPropertyValue(const QualifiedName& attribute_name) const {
return svg_attribute_map_.at(&attribute_name);
}
PropertyHandleSet Properties() const override;
void AddKeyframePropertiesToV8Object(V8ObjectBuilder&) const override;
class CSSPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
public:
static scoped_refptr<CSSPropertySpecificKeyframe> Create(
double offset,
scoped_refptr<TimingFunction> easing,
const CSSValue* value,
EffectModel::CompositeOperation composite) {
return base::AdoptRef(new CSSPropertySpecificKeyframe(
offset, std::move(easing), value, composite));
}
const CSSValue* Value() const { return value_.Get(); }
bool PopulateAnimatableValue(const CSSProperty&,
Element&,
const ComputedStyle& base_style,
const ComputedStyle* parent_style) const final;
const AnimatableValue* GetAnimatableValue() const final {
return animatable_value_cache_.get();
}
bool IsNeutral() const final { return !value_; }
scoped_refptr<Keyframe::PropertySpecificKeyframe> NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const final;
private:
CSSPropertySpecificKeyframe(double offset,
scoped_refptr<TimingFunction> easing,
const CSSValue* value,
EffectModel::CompositeOperation composite)
: Keyframe::PropertySpecificKeyframe(offset,
std::move(easing),
composite),
value_(const_cast<CSSValue*>(value)) {}
scoped_refptr<Keyframe::PropertySpecificKeyframe> CloneWithOffset(
double offset) const override;
bool IsCSSPropertySpecificKeyframe() const override { return true; }
// TODO(sashab): Make this a const CSSValue.
Persistent<CSSValue> value_;
mutable scoped_refptr<AnimatableValue> animatable_value_cache_;
};
class SVGPropertySpecificKeyframe
: public Keyframe::PropertySpecificKeyframe {
public:
static scoped_refptr<SVGPropertySpecificKeyframe> Create(
double offset,
scoped_refptr<TimingFunction> easing,
const String& value,
EffectModel::CompositeOperation composite) {
return base::AdoptRef(new SVGPropertySpecificKeyframe(
offset, std::move(easing), value, composite));
}
const String& Value() const { return value_; }
scoped_refptr<PropertySpecificKeyframe> CloneWithOffset(
double offset) const final;
const AnimatableValue* GetAnimatableValue() const final { return nullptr; }
bool IsNeutral() const final { return value_.IsNull(); }
scoped_refptr<PropertySpecificKeyframe> NeutralKeyframe(
double offset,
scoped_refptr<TimingFunction> easing) const final;
private:
SVGPropertySpecificKeyframe(double offset,
scoped_refptr<TimingFunction> easing,
const String& value,
EffectModel::CompositeOperation composite)
: Keyframe::PropertySpecificKeyframe(offset,
std::move(easing),
composite),
value_(value) {}
bool IsSVGPropertySpecificKeyframe() const override { return true; }
String value_;
};
private:
StringKeyframe()
: css_property_map_(
MutableCSSPropertyValueSet::Create(kHTMLStandardMode)),
presentation_attribute_map_(
MutableCSSPropertyValueSet::Create(kHTMLStandardMode)) {}
StringKeyframe(const StringKeyframe& copy_from);
scoped_refptr<Keyframe> Clone() const override;
scoped_refptr<Keyframe::PropertySpecificKeyframe>
CreatePropertySpecificKeyframe(const PropertyHandle&,
double offset) const override;
bool IsStringKeyframe() const override { return true; }
Persistent<MutableCSSPropertyValueSet> css_property_map_;
Persistent<MutableCSSPropertyValueSet> presentation_attribute_map_;
HashMap<const QualifiedName*, String> svg_attribute_map_;
};
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