chromium/third_party/blink/renderer/core/animation/css/css_animations.cc

/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#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 {};

// A keyframe can have an offset as a fixed percent or as a
// <timeline-range percent>. In the later case, we store the specified
// offset on the Keyframe, and delay the resolution that offset until later.
// (See ResolveTimelineOffset).
bool SetOffsets(Keyframe& keyframe, const KeyframeOffset& offset) {}

// Processes keyframe rules, extracting the timing function and properties being
// animated for each keyframe. The extraction process is doing more work that
// strictly required for the setup to step 6 in the spec
// (https://drafts.csswg.org/css-animations-2/#keyframes) as an optimization
// to avoid needing to process each rule multiple times to extract different
// properties.
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) {}

// Finds the index of a keyframe with matching offset and easing.
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) {}

// Returns the start time of an animation given the start delay. A negative
// start delay results in the animation starting with non-zero progress.
AnimationTimeDelta StartTimeFromDelay(AnimationTimeDelta start_delay) {}

// Timing functions for computing elapsed time of an event.

AnimationTimeDelta IntervalStart(const AnimationEffect& effect) {}

AnimationTimeDelta IntervalEnd(const AnimationEffect& effect) {}

AnimationTimeDelta IterationElapsedTime(const AnimationEffect& effect,
                                        double previous_iteration) {}

const CSSAnimationUpdate* GetPendingAnimationUpdate(Node& node) {}

// SpecifiedTimelines "zips" together name/axis/inset vectors such that
// individual name/axis/inset values can be accessed as a tuple.
//
// SpecifiedTimelines skips over entries with nullptr-names (which
// represents "none"), because such entries should not yield timelines.
class SpecifiedTimelines {};

class SpecifiedScrollTimelines : public SpecifiedTimelines {};

class SpecifiedViewTimelines : public SpecifiedTimelines {};

// Invokes `callback` for each timeline we would end up with had
// `changed_timelines` been applied to `existing_timelines`.
template <typename TimelineType, typename CallbackFunc>
void ForEachTimeline(const CSSTimelineMap<TimelineType>* existing_timelines,
                     const CSSTimelineMap<TimelineType>* changed_timelines,
                     CallbackFunc callback) {}

// When calculating timeline updates, we initially assume that all timelines
// are going to be removed, and then erase the nullptr entries for timelines
// where we discover that this doesn't apply.
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) {}

// The CSSScrollTimelineOptions and CSSViewTimelineOptions structs exist
// in order to avoid creating a new Scroll/ViewTimeline when doing so
// would anyway result in exactly the same Scroll/ViewTimeline that we
// already have. (See TimelineMatches functions).

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) {}

}  // namespace

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 {

// Assuming that `inner` is an inclusive descendant of `outer`, returns
// the distance (in the number of TreeScopes) between `inner` and `outer`.
//
// Returns std::numeric_limits::max() if `inner` is not an inclusive
// descendant of `outer`.
size_t TreeScopeDistance(const TreeScope* outer, const TreeScope* inner) {}

// Update the matching timeline if the candidate is a more proximate match
// than the existing match.
template <typename TimelineType>
void UpdateMatchingTimeline(const ScopedCSSName& target_name,
                            const ScopedCSSName& candidate_name,
                            TimelineType* candidate,
                            TimelineType*& matching_timeline,
                            size_t& matching_distance) {}

}  // namespace

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) {}

// Find a ScrollSnapshotTimeline in inclusive ancestors.
//
// The reason `update` is provided from the outside rather than just fetching
// it from ElementAnimations, is that for the current node we're resolving style
// for, the update hasn't actually been stored on ElementAnimations yet.
ScrollSnapshotTimeline* CSSAnimations::FindAncestorTimeline(
    const ScopedCSSName& name,
    Node* node,
    const CSSAnimationUpdate* update) {}

// Like FindAncestorTimeline, but only looks for DeferredTimelines.
// This is used to attach Scroll/ViewTimelines to any matching DeferredTimelines
// in the ancestor chain.
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) {}

}  // namespace

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) {}

}  // namespace

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) {}

// Called for animations that are newly created or updated.
void UpdateAnimationFlagsForInertEffect(const InertEffect& effect,
                                        ComputedStyleBuilder& builder) {}

// Called for existing animations that are not modified in this update.
void UpdateAnimationFlagsForAnimation(const Animation& animation,
                                      ComputedStyleBuilder& builder) {}

}  // namespace

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) {}

// TODO(alancutter): CSS properties and presentation attributes may have
// identical effects. By grouping them in the same set we introduce a bug where
// arbitrary hash iteration will determine the order the apply in and thus which
// one "wins". We should be more deliberate about the order of application in
// the case of effect collisions.
// Example: Both 'color' and 'svg-color' set the color on ComputedStyle but are
// considered distinct properties in the ActiveInterpolationsMap.
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) {}

}  // namespace

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) {}

// Properties that affect animations are not allowed to be affected by
// animations.
// https://w3.org/TR/web-animations-1/#animating-properties
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 {}

}  // namespace blink