#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include <algorithm>
#include <bitset>
#include <tuple>
#include "base/containers/contains.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_cssnumericvalue_double.h"
#include "third_party/blink/renderer/core/animation/animation.h"
#include "third_party/blink/renderer/core/animation/animation_utils.h"
#include "third_party/blink/renderer/core/animation/compositor_animations.h"
#include "third_party/blink/renderer/core/animation/css/compositor_keyframe_value_factory.h"
#include "third_party/blink/renderer/core/animation/css/css_animation.h"
#include "third_party/blink/renderer/core/animation/css/css_keyframe_effect_model.h"
#include "third_party/blink/renderer/core/animation/css/css_transition.h"
#include "third_party/blink/renderer/core/animation/css_default_interpolation_type.h"
#include "third_party/blink/renderer/core/animation/css_interpolation_types_map.h"
#include "third_party/blink/renderer/core/animation/document_animations.h"
#include "third_party/blink/renderer/core/animation/document_timeline.h"
#include "third_party/blink/renderer/core/animation/element_animations.h"
#include "third_party/blink/renderer/core/animation/inert_effect.h"
#include "third_party/blink/renderer/core/animation/interpolable_length.h"
#include "third_party/blink/renderer/core/animation/interpolation.h"
#include "third_party/blink/renderer/core/animation/interpolation_environment.h"
#include "third_party/blink/renderer/core/animation/interpolation_type.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect.h"
#include "third_party/blink/renderer/core/animation/keyframe_effect_model.h"
#include "third_party/blink/renderer/core/animation/timing.h"
#include "third_party/blink/renderer/core/animation/timing_calculations.h"
#include "third_party/blink/renderer/core/animation/transition_interpolation.h"
#include "third_party/blink/renderer/core/animation/worklet_animation_base.h"
#include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
#include "third_party/blink/renderer/core/css/css_property_equality.h"
#include "third_party/blink/renderer/core/css/css_value_list.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
#include "third_party/blink/renderer/core/css/post_style_update_scope.h"
#include "third_party/blink/renderer/core/css/properties/computed_style_utils.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css/properties/css_property_ref.h"
#include "third_party/blink/renderer/core/css/properties/longhands.h"
#include "third_party/blink/renderer/core/css/property_registry.h"
#include "third_party/blink/renderer/core/css/resolver/css_to_style_map.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_engine.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/dom/events/event_path.h"
#include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/dom/pseudo_element.h"
#include "third_party/blink/renderer/core/dom/shadow_root.h"
#include "third_party/blink/renderer/core/events/animation_event.h"
#include "third_party/blink/renderer/core/events/transition_event.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/style_property_shorthand.h"
#include "third_party/blink/renderer/platform/animation/timing_function.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
namespace blink {
PropertySet;
namespace {
class CSSAnimationProxy : public AnimationProxy { … };
CSSAnimationProxy::CSSAnimationProxy(
AnimationTimeline* timeline,
CSSAnimation* animation,
bool is_paused,
const std::optional<TimelineOffset>& range_start,
const std::optional<TimelineOffset>& range_end,
const Timing& timing)
: … { … }
std::optional<AnimationTimeDelta> CSSAnimationProxy::CalculateInheritedTime(
AnimationTimeline* timeline,
CSSAnimation* animation,
const std::optional<TimelineOffset>& range_start,
const std::optional<TimelineOffset>& range_end,
const Timing& timing) { … }
class CSSTransitionProxy : public AnimationProxy { … };
bool SetOffsets(Keyframe& keyframe, const KeyframeOffset& offset) { … }
StringKeyframeVector ProcessKeyframesRule(
const StyleRuleKeyframes* keyframes_rule,
const TreeScope* tree_scope,
const Document& document,
const ComputedStyle* parent_style,
TimingFunction* default_timing_function,
WritingDirectionMode writing_direction,
bool& has_named_range_keyframes) { … }
std::optional<int> FindIndexOfMatchingKeyframe(
const StringKeyframeVector& keyframes,
wtf_size_t start_index,
std::optional<double> offset,
std::optional<TimelineOffset> timeline_offset,
const TimingFunction& easing,
const std::optional<EffectModel::CompositeOperation>& composite) { … }
StringKeyframeEffectModel* CreateKeyframeEffectModel(
StyleResolver* resolver,
Element& element,
const Element& animating_element,
WritingDirectionMode writing_direction,
const ComputedStyle* parent_style,
const AtomicString& name,
TimingFunction* default_timing_function,
EffectModel::CompositeOperation composite,
size_t animation_index) { … }
AnimationTimeDelta StartTimeFromDelay(AnimationTimeDelta start_delay) { … }
AnimationTimeDelta IntervalStart(const AnimationEffect& effect) { … }
AnimationTimeDelta IntervalEnd(const AnimationEffect& effect) { … }
AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect,
double previous_iteration) { … }
const CSSAnimationUpdate* GetPendingAnimationUpdate(Node& node) { … }
class SpecifiedTimelines { … };
class SpecifiedScrollTimelines : public SpecifiedTimelines { … };
class SpecifiedViewTimelines : public SpecifiedTimelines { … };
template <typename TimelineType, typename CallbackFunc>
void ForEachTimeline(const CSSTimelineMap<TimelineType>* existing_timelines,
const CSSTimelineMap<TimelineType>* changed_timelines,
CallbackFunc callback) { … }
template <typename MapType>
MapType NullifyExistingTimelines(const MapType* existing_timelines) { … }
template <typename TimelineType>
TimelineType* GetTimeline(const CSSTimelineMap<TimelineType>* timelines,
const ScopedCSSName& name) { … }
DeferredTimeline* GetTimelineAttachment(
const TimelineAttachmentMap* timeline_attachments,
ScrollSnapshotTimeline* timeline) { … }
Element* ParentElementForTimelineTraversal(Node& node) { … }
Element* ResolveReferenceElement(Document& document,
TimelineScroller scroller,
Element* reference_element) { … }
ScrollTimeline::ReferenceType ComputeReferenceType(TimelineScroller scroller) { … }
ScrollTimeline::ScrollAxis ComputeAxis(TimelineAxis axis) { … }
struct CSSScrollTimelineOptions { … };
struct CSSViewTimelineOptions { … };
bool TimelineMatches(const ScrollTimeline& timeline,
const CSSScrollTimelineOptions& options) { … }
bool TimelineMatches(const ViewTimeline& timeline,
const CSSViewTimelineOptions& options) { … }
Vector<const CSSProperty*> PropertiesForTransitionAll(
bool with_discrete,
const ExecutionContext* execution_context) { … }
const StylePropertyShorthand& PropertiesForTransitionAllDiscrete(
const ExecutionContext* execution_context) { … }
const StylePropertyShorthand& PropertiesForTransitionAllNormal(
const ExecutionContext* execution_context) { … }
}
void CSSAnimations::CalculateScrollTimelineUpdate(
CSSAnimationUpdate& update,
Element& animating_element,
const ComputedStyleBuilder& style_builder) { … }
void CSSAnimations::CalculateViewTimelineUpdate(
CSSAnimationUpdate& update,
Element& animating_element,
const ComputedStyleBuilder& style_builder) { … }
void CSSAnimations::CalculateDeferredTimelineUpdate(
CSSAnimationUpdate& update,
Element& animating_element,
const ComputedStyleBuilder& style_builder) { … }
CSSScrollTimelineMap CSSAnimations::CalculateChangedScrollTimelines(
Element& animating_element,
const CSSScrollTimelineMap* existing_scroll_timelines,
const ComputedStyleBuilder& style_builder) { … }
CSSViewTimelineMap CSSAnimations::CalculateChangedViewTimelines(
Element& animating_element,
const CSSViewTimelineMap* existing_view_timelines,
const ComputedStyleBuilder& style_builder) { … }
CSSDeferredTimelineMap CSSAnimations::CalculateChangedDeferredTimelines(
Element& animating_element,
const CSSDeferredTimelineMap* existing_deferred_timelines,
const ComputedStyleBuilder& style_builder) { … }
template <>
const CSSScrollTimelineMap*
CSSAnimations::GetExistingTimelines<CSSScrollTimelineMap>(
const TimelineData* data) { … }
template <>
const CSSScrollTimelineMap*
CSSAnimations::GetChangedTimelines<CSSScrollTimelineMap>(
const CSSAnimationUpdate* update) { … }
template <>
const CSSViewTimelineMap*
CSSAnimations::GetExistingTimelines<CSSViewTimelineMap>(
const TimelineData* data) { … }
template <>
const CSSViewTimelineMap*
CSSAnimations::GetChangedTimelines<CSSViewTimelineMap>(
const CSSAnimationUpdate* update) { … }
template <>
const CSSDeferredTimelineMap*
CSSAnimations::GetExistingTimelines<CSSDeferredTimelineMap>(
const TimelineData* data) { … }
template <>
const CSSDeferredTimelineMap*
CSSAnimations::GetChangedTimelines<CSSDeferredTimelineMap>(
const CSSAnimationUpdate* update) { … }
template <typename TimelineType, typename CallbackFunc>
void CSSAnimations::ForEachTimeline(const TimelineData* timeline_data,
const CSSAnimationUpdate* update,
CallbackFunc callback) { … }
template <typename TimelineType>
void CSSAnimations::CalculateChangedTimelineAttachments(
Element& animating_element,
const TimelineData* timeline_data,
const CSSAnimationUpdate& update,
const TimelineAttachmentMap* existing_attachments,
TimelineAttachmentMap& result) { … }
void CSSAnimations::CalculateTimelineAttachmentUpdate(
CSSAnimationUpdate& update,
Element& animating_element) { … }
const CSSAnimations::TimelineData* CSSAnimations::GetTimelineData(
const Element& element) { … }
namespace {
size_t TreeScopeDistance(const TreeScope* outer, const TreeScope* inner) { … }
template <typename TimelineType>
void UpdateMatchingTimeline(const ScopedCSSName& target_name,
const ScopedCSSName& candidate_name,
TimelineType* candidate,
TimelineType*& matching_timeline,
size_t& matching_distance) { … }
}
ScrollSnapshotTimeline* CSSAnimations::FindTimelineForNode(
const ScopedCSSName& name,
Node* node,
const CSSAnimationUpdate* update) { … }
template <typename TimelineType>
TimelineType* CSSAnimations::FindTimelineForElement(
const ScopedCSSName& target_name,
const TimelineData* timeline_data,
const CSSAnimationUpdate* update) { … }
ScrollSnapshotTimeline* CSSAnimations::FindAncestorTimeline(
const ScopedCSSName& name,
Node* node,
const CSSAnimationUpdate* update) { … }
DeferredTimeline* CSSAnimations::FindDeferredTimeline(
const ScopedCSSName& name,
Element* element,
const CSSAnimationUpdate* update) { … }
namespace {
ScrollTimeline* ComputeScrollFunctionTimeline(
Element* element,
const StyleTimeline::ScrollData& scroll_data,
AnimationTimeline* existing_timeline) { … }
AnimationTimeline* ComputeViewFunctionTimeline(
Element* element,
const StyleTimeline::ViewData& view_data,
AnimationTimeline* existing_timeline) { … }
}
AnimationTimeline* CSSAnimations::ComputeTimeline(
Element* element,
const StyleTimeline& style_timeline,
const CSSAnimationUpdate& update,
AnimationTimeline* existing_timeline) { … }
CSSAnimations::CSSAnimations() = default;
namespace {
const KeyframeEffectModelBase* GetKeyframeEffectModelBase(
const AnimationEffect* effect) { … }
bool ComputedValuesEqual(const PropertyHandle& property,
const ComputedStyle& a,
const ComputedStyle& b) { … }
}
void CSSAnimations::CalculateCompositorAnimationUpdate(
CSSAnimationUpdate& update,
const Element& animating_element,
Element& element,
const ComputedStyle& style,
const ComputedStyle* parent_style,
bool was_viewport_resized,
bool force_update) { … }
void CSSAnimations::CalculateTimelineUpdate(
CSSAnimationUpdate& update,
Element& animating_element,
const ComputedStyleBuilder& style_builder) { … }
void CSSAnimations::CalculateAnimationUpdate(
CSSAnimationUpdate& update,
Element& animating_element,
Element& element,
const ComputedStyleBuilder& style_builder,
const ComputedStyle* parent_style,
StyleResolver* resolver,
bool can_trigger_animations) { … }
AnimationEffect::EventDelegate* CSSAnimations::CreateEventDelegate(
Element* element,
const PropertyHandle& property_handle,
const AnimationEffect::EventDelegate* old_event_delegate) { … }
AnimationEffect::EventDelegate* CSSAnimations::CreateEventDelegate(
Element* element,
const AtomicString& animation_name,
const AnimationEffect::EventDelegate* old_event_delegate) { … }
void CSSAnimations::SnapshotCompositorKeyframes(
Element& element,
CSSAnimationUpdate& update,
const ComputedStyle& style,
const ComputedStyle* parent_style) { … }
namespace {
bool AffectsBackgroundColor(const AnimationEffect& effect) { … }
void UpdateAnimationFlagsForEffect(const AnimationEffect& effect,
ComputedStyleBuilder& builder) { … }
void UpdateAnimationFlagsForInertEffect(const InertEffect& effect,
ComputedStyleBuilder& builder) { … }
void UpdateAnimationFlagsForAnimation(const Animation& animation,
ComputedStyleBuilder& builder) { … }
}
void CSSAnimations::UpdateAnimationFlags(Element& animating_element,
CSSAnimationUpdate& update,
ComputedStyleBuilder& builder) { … }
void CSSAnimations::MaybeApplyPendingUpdate(Element* element) { … }
HeapHashSet<Member<const Animation>>
CSSAnimations::CreateCancelledTransitionsSet(
ElementAnimations* element_animations,
CSSAnimationUpdate& update) { … }
bool CSSAnimations::CanCalculateTransitionUpdateForProperty(
TransitionUpdateState& state,
const PropertyHandle& property) { … }
void CSSAnimations::CalculateTransitionUpdateForPropertyHandle(
TransitionUpdateState& state,
const CSSTransitionData::TransitionAnimationType type,
const PropertyHandle& property,
wtf_size_t transition_index,
bool animate_all) { … }
void CSSAnimations::CalculateTransitionUpdateForProperty(
TransitionUpdateState& state,
const CSSTransitionData::TransitionProperty& transition_property,
wtf_size_t transition_index,
WritingDirectionMode writing_direction) { … }
void CSSAnimations::CalculateTransitionUpdateForCustomProperty(
TransitionUpdateState& state,
const CSSTransitionData::TransitionProperty& transition_property,
wtf_size_t transition_index) { … }
void CSSAnimations::CalculateTransitionUpdateForStandardProperty(
TransitionUpdateState& state,
const CSSTransitionData::TransitionProperty& transition_property,
wtf_size_t transition_index,
WritingDirectionMode writing_direction) { … }
void CSSAnimations::CalculateTransitionUpdate(
CSSAnimationUpdate& update,
Element& animating_element,
const ComputedStyleBuilder& style_builder,
const ComputedStyle* old_style,
bool can_trigger_animations) { … }
const ComputedStyle* CSSAnimations::CalculateBeforeChangeStyle(
Element& animating_element,
const ComputedStyle& base_style) { … }
void CSSAnimations::Cancel() { … }
void CSSAnimations::TimelineData::SetScrollTimeline(const ScopedCSSName& name,
ScrollTimeline* timeline) { … }
void CSSAnimations::TimelineData::SetViewTimeline(const ScopedCSSName& name,
ViewTimeline* timeline) { … }
void CSSAnimations::TimelineData::SetDeferredTimeline(
const ScopedCSSName& name,
DeferredTimeline* timeline) { … }
void CSSAnimations::TimelineData::SetTimelineAttachment(
ScrollSnapshotTimeline* attached_timeline,
DeferredTimeline* deferred_timeline) { … }
DeferredTimeline* CSSAnimations::TimelineData::GetTimelineAttachment(
ScrollSnapshotTimeline* attached_timeline) { … }
void CSSAnimations::TimelineData::Trace(blink::Visitor* visitor) const { … }
namespace {
bool IsCustomPropertyHandle(const PropertyHandle& property) { … }
bool IsFontAffectingPropertyHandle(const PropertyHandle& property) { … }
bool IsCSSPropertyHandle(const PropertyHandle& property) { … }
bool IsLineHeightPropertyHandle(const PropertyHandle& property) { … }
bool IsDisplayPropertyHandle(const PropertyHandle& property) { … }
void AdoptActiveAnimationInterpolations(
EffectStack* effect_stack,
CSSAnimationUpdate& update,
const HeapVector<Member<const InertEffect>>* new_animations,
const HeapHashSet<Member<const Animation>>* suppressed_animations) { … }
}
void CSSAnimations::CalculateAnimationActiveInterpolations(
CSSAnimationUpdate& update,
const Element& animating_element) { … }
void CSSAnimations::CalculateTransitionActiveInterpolations(
CSSAnimationUpdate& update,
const Element& animating_element) { … }
EventTarget* CSSAnimations::AnimationEventDelegate::GetEventTarget() const { … }
void CSSAnimations::AnimationEventDelegate::MaybeDispatch(
Document::ListenerType listener_type,
const AtomicString& event_name,
const AnimationTimeDelta& elapsed_time) { … }
bool CSSAnimations::AnimationEventDelegate::RequiresIterationEvents(
const AnimationEffect& animation_node) { … }
void CSSAnimations::AnimationEventDelegate::OnEventCondition(
const AnimationEffect& animation_node,
Timing::Phase current_phase) { … }
void CSSAnimations::AnimationEventDelegate::Trace(Visitor* visitor) const { … }
EventTarget* CSSAnimations::TransitionEventDelegate::GetEventTarget() const { … }
void CSSAnimations::TransitionEventDelegate::OnEventCondition(
const AnimationEffect& animation_node,
Timing::Phase current_phase) { … }
void CSSAnimations::TransitionEventDelegate::EnqueueEvent(
const WTF::AtomicString& type,
const AnimationTimeDelta& elapsed_time) { … }
void CSSAnimations::TransitionEventDelegate::Trace(Visitor* visitor) const { … }
const StylePropertyShorthand& CSSAnimations::PropertiesForTransitionAll(
bool with_discrete,
const ExecutionContext* execution_context) { … }
bool CSSAnimations::IsAnimationAffectingProperty(const CSSProperty& property) { … }
bool CSSAnimations::IsAffectedByKeyframesFromScope(
const Element& element,
const TreeScope& tree_scope) { … }
bool CSSAnimations::IsAnimatingCustomProperties(
const ElementAnimations* element_animations) { … }
bool CSSAnimations::IsAnimatingStandardProperties(
const ElementAnimations* element_animations,
const CSSBitset* bitset,
KeyframeEffect::Priority priority) { … }
bool CSSAnimations::IsAnimatingFontAffectingProperties(
const ElementAnimations* element_animations) { … }
bool CSSAnimations::IsAnimatingLineHeightProperty(
const ElementAnimations* element_animations) { … }
bool CSSAnimations::IsAnimatingRevert(
const ElementAnimations* element_animations) { … }
bool CSSAnimations::IsAnimatingDisplayProperty(
const ElementAnimations* element_animations) { … }
void CSSAnimations::Trace(Visitor* visitor) const { … }
}