blob: 90503cb03c2c0067412852811f30804bc59e7592 [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.
#include "core/animation/StringKeyframe.h"
#include "core/StylePropertyShorthand.h"
#include "core/animation/css/CSSAnimations.h"
#include "core/css/CSSCustomPropertyDeclaration.h"
#include "core/css/CSSPropertyMetadata.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/svg/SVGElement.h"
#include "platform/RuntimeEnabledFeatures.h"
namespace blink {
StringKeyframe::StringKeyframe(const StringKeyframe& copy_from)
: Keyframe(copy_from.offset_, copy_from.composite_, copy_from.easing_),
css_property_map_(copy_from.css_property_map_->MutableCopy()),
presentation_attribute_map_(
copy_from.presentation_attribute_map_->MutableCopy()),
svg_attribute_map_(copy_from.svg_attribute_map_) {}
MutableStylePropertySet::SetResult StringKeyframe::SetCSSPropertyValue(
const AtomicString& property_name,
const PropertyRegistry* registry,
const String& value,
StyleSheetContents* style_sheet_contents) {
bool is_animation_tainted = true;
return css_property_map_->SetProperty(property_name, registry, value, false,
style_sheet_contents,
is_animation_tainted);
}
MutableStylePropertySet::SetResult StringKeyframe::SetCSSPropertyValue(
CSSPropertyID property,
const String& value,
StyleSheetContents* style_sheet_contents) {
DCHECK_NE(property, CSSPropertyInvalid);
if (CSSAnimations::IsAnimationAffectingProperty(property)) {
bool did_parse = true;
bool did_change = false;
return MutableStylePropertySet::SetResult{did_parse, did_change};
}
return css_property_map_->SetProperty(property, value, false,
style_sheet_contents);
}
void StringKeyframe::SetCSSPropertyValue(CSSPropertyID property,
const CSSValue& value) {
DCHECK_NE(property, CSSPropertyInvalid);
DCHECK(!CSSAnimations::IsAnimationAffectingProperty(property));
css_property_map_->SetProperty(property, value, false);
}
void StringKeyframe::SetPresentationAttributeValue(
CSSPropertyID property,
const String& value,
StyleSheetContents* style_sheet_contents) {
DCHECK_NE(property, CSSPropertyInvalid);
if (!CSSAnimations::IsAnimationAffectingProperty(property))
presentation_attribute_map_->SetProperty(property, value, false,
style_sheet_contents);
}
void StringKeyframe::SetSVGAttributeValue(const QualifiedName& attribute_name,
const String& value) {
svg_attribute_map_.Set(&attribute_name, value);
}
PropertyHandleSet StringKeyframe::Properties() const {
// This is not used in time-critical code, so we probably don't need to
// worry about caching this result.
PropertyHandleSet properties;
for (unsigned i = 0; i < css_property_map_->PropertyCount(); ++i) {
StylePropertySet::PropertyReference property_reference =
css_property_map_->PropertyAt(i);
DCHECK(!isShorthandProperty(property_reference.Id()))
<< "Web Animations: Encountered unexpanded shorthand CSS property ("
<< property_reference.Id() << ").";
if (property_reference.Id() == CSSPropertyVariable)
properties.insert(PropertyHandle(
ToCSSCustomPropertyDeclaration(property_reference.Value())
.GetName()));
else
properties.insert(PropertyHandle(property_reference.Id(), false));
}
for (unsigned i = 0; i < presentation_attribute_map_->PropertyCount(); ++i)
properties.insert(
PropertyHandle(presentation_attribute_map_->PropertyAt(i).Id(), true));
for (const auto& key : svg_attribute_map_.Keys())
properties.insert(PropertyHandle(*key));
return properties;
}
PassRefPtr<Keyframe> StringKeyframe::Clone() const {
return AdoptRef(new StringKeyframe(*this));
}
PassRefPtr<Keyframe::PropertySpecificKeyframe>
StringKeyframe::CreatePropertySpecificKeyframe(
const PropertyHandle& property) const {
if (property.IsCSSProperty())
return CSSPropertySpecificKeyframe::Create(
Offset(), &Easing(), &CssPropertyValue(property), Composite());
if (property.IsPresentationAttribute())
return CSSPropertySpecificKeyframe::Create(
Offset(), &Easing(),
&PresentationAttributeValue(property.PresentationAttribute()),
Composite());
DCHECK(property.IsSVGAttribute());
return SVGPropertySpecificKeyframe::Create(
Offset(), &Easing(), SvgPropertyValue(property.SvgAttribute()),
Composite());
}
bool StringKeyframe::CSSPropertySpecificKeyframe::PopulateAnimatableValue(
CSSPropertyID property,
Element& element,
const ComputedStyle& base_style,
const ComputedStyle* parent_style) const {
animatable_value_cache_ = StyleResolver::CreateAnimatableValueSnapshot(
element, base_style, parent_style, property, value_.Get());
return true;
}
PassRefPtr<Keyframe::PropertySpecificKeyframe>
StringKeyframe::CSSPropertySpecificKeyframe::NeutralKeyframe(
double offset,
PassRefPtr<TimingFunction> easing) const {
return Create(offset, std::move(easing), nullptr, EffectModel::kCompositeAdd);
}
PassRefPtr<Keyframe::PropertySpecificKeyframe>
StringKeyframe::CSSPropertySpecificKeyframe::CloneWithOffset(
double offset) const {
RefPtr<CSSPropertySpecificKeyframe> clone =
Create(offset, easing_, value_.Get(), composite_);
clone->animatable_value_cache_ = animatable_value_cache_;
return clone;
}
PassRefPtr<Keyframe::PropertySpecificKeyframe>
SVGPropertySpecificKeyframe::CloneWithOffset(double offset) const {
return Create(offset, easing_, value_, composite_);
}
PassRefPtr<Keyframe::PropertySpecificKeyframe>
SVGPropertySpecificKeyframe::NeutralKeyframe(
double offset,
PassRefPtr<TimingFunction> easing) const {
return Create(offset, std::move(easing), String(),
EffectModel::kCompositeAdd);
}
} // namespace blink