replaced by .editorconfig # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D287843
217 lines
7.2 KiB
C++
217 lines
7.2 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_ElementAnimationData_h
|
|
#define mozilla_ElementAnimationData_h
|
|
|
|
#include "mozilla/PseudoStyleRequest.h"
|
|
#include "mozilla/UniquePtr.h"
|
|
#include "nsTHashMap.h"
|
|
|
|
class nsCycleCollectionTraversalCallback;
|
|
|
|
namespace mozilla {
|
|
class EffectSet;
|
|
template <typename Animation>
|
|
class AnimationCollection;
|
|
template <typename TimelineType>
|
|
class TimelineCollection;
|
|
namespace dom {
|
|
class Element;
|
|
class CSSAnimation;
|
|
class CSSTransition;
|
|
class ScrollTimeline;
|
|
class ViewTimeline;
|
|
} // namespace dom
|
|
using CSSAnimationCollection = AnimationCollection<dom::CSSAnimation>;
|
|
using CSSTransitionCollection = AnimationCollection<dom::CSSTransition>;
|
|
using ScrollTimelineCollection = TimelineCollection<dom::ScrollTimeline>;
|
|
using ViewTimelineCollection = TimelineCollection<dom::ViewTimeline>;
|
|
|
|
// The animation data for a given element (and its pseudo-elements).
|
|
class ElementAnimationData {
|
|
struct PerElementOrPseudoData {
|
|
UniquePtr<EffectSet> mEffectSet;
|
|
UniquePtr<CSSAnimationCollection> mAnimations;
|
|
UniquePtr<CSSTransitionCollection> mTransitions;
|
|
|
|
// Note: scroll-timeline-name is applied to elements which could be
|
|
// scroll containers, or replaced elements. view-timeline-name is applied to
|
|
// all elements. However, the named timeline is referenceable in
|
|
// animation-timeline by the tree order scope.
|
|
// Spec: https://drafts.csswg.org/scroll-animations-1/#timeline-scope.
|
|
//
|
|
// So it should be fine to create timeline objects only on the elements and
|
|
// pseudo elements which support animations.
|
|
//
|
|
// Note: TimelineCollection owns and manages the named progress timeline
|
|
// generated by specifying scroll-timeline-name property and
|
|
// view-timeline-name property on this element. However, the anonymous
|
|
// progress timelines (e.g. animation-timeline:scroll()) are owned by
|
|
// Animation objects only.
|
|
UniquePtr<ScrollTimelineCollection> mScrollTimelines;
|
|
UniquePtr<ViewTimelineCollection> mViewTimelines;
|
|
|
|
PerElementOrPseudoData();
|
|
~PerElementOrPseudoData();
|
|
|
|
EffectSet& DoEnsureEffectSet();
|
|
CSSTransitionCollection& DoEnsureTransitions(dom::Element&,
|
|
const PseudoStyleRequest&);
|
|
CSSAnimationCollection& DoEnsureAnimations(dom::Element&,
|
|
const PseudoStyleRequest&);
|
|
ScrollTimelineCollection& DoEnsureScrollTimelines(
|
|
dom::Element&, const PseudoStyleRequest&);
|
|
ViewTimelineCollection& DoEnsureViewTimelines(dom::Element&,
|
|
const PseudoStyleRequest&);
|
|
|
|
bool IsEmpty() const {
|
|
return !mEffectSet && !mAnimations && !mTransitions &&
|
|
!mScrollTimelines && !mViewTimelines;
|
|
}
|
|
|
|
void Traverse(nsCycleCollectionTraversalCallback&);
|
|
};
|
|
|
|
PerElementOrPseudoData mElementData;
|
|
|
|
using PseudoData =
|
|
nsTHashMap<PseudoStyleRequestHashKey, UniquePtr<PerElementOrPseudoData>>;
|
|
PseudoData mPseudoData;
|
|
// Avoid remove hash entry while other people are still using it.
|
|
bool mIsClearingPseudoData = false;
|
|
|
|
const PerElementOrPseudoData* GetData(
|
|
const PseudoStyleRequest& aRequest) const {
|
|
if (aRequest.mType != PseudoStyleType::NotPseudo) {
|
|
return GetPseudoData(aRequest);
|
|
}
|
|
return &mElementData;
|
|
}
|
|
|
|
PerElementOrPseudoData& GetOrCreateData(const PseudoStyleRequest& aRequest) {
|
|
if (aRequest.mType != PseudoStyleType::NotPseudo) {
|
|
return GetOrCreatePseudoData(aRequest);
|
|
}
|
|
return mElementData;
|
|
}
|
|
|
|
const PerElementOrPseudoData* GetPseudoData(
|
|
const PseudoStyleRequest& aRequest) const;
|
|
PerElementOrPseudoData& GetOrCreatePseudoData(
|
|
const PseudoStyleRequest& aRequest);
|
|
void MaybeClearEntry(PseudoData::LookupResult<PseudoData&>&& aEntry);
|
|
|
|
// |aFn| is the removal function which accepts only |PerElementOrPseudoData&|
|
|
// as the parameter.
|
|
template <typename Fn>
|
|
void WithDataForRemoval(const PseudoStyleRequest& aRequest, Fn&& aFn);
|
|
|
|
public:
|
|
void Traverse(nsCycleCollectionTraversalCallback&);
|
|
|
|
void ClearAllAnimationCollections();
|
|
void ClearAllPseudos(bool aOnlyViewTransitions);
|
|
void ClearViewTransitionPseudos() { ClearAllPseudos(true); }
|
|
|
|
EffectSet* GetEffectSetFor(const PseudoStyleRequest& aRequest) const {
|
|
if (auto* data = GetData(aRequest)) {
|
|
return data->mEffectSet.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void ClearEffectSetFor(const PseudoStyleRequest& aRequest);
|
|
|
|
EffectSet& EnsureEffectSetFor(const PseudoStyleRequest& aRequest) {
|
|
auto& data = GetOrCreateData(aRequest);
|
|
if (auto* set = data.mEffectSet.get()) {
|
|
return *set;
|
|
}
|
|
return data.DoEnsureEffectSet();
|
|
}
|
|
|
|
CSSTransitionCollection* GetTransitionCollection(
|
|
const PseudoStyleRequest& aRequest) const {
|
|
if (auto* data = GetData(aRequest)) {
|
|
return data->mTransitions.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void ClearTransitionCollectionFor(const PseudoStyleRequest& aRequest);
|
|
|
|
CSSTransitionCollection& EnsureTransitionCollection(
|
|
dom::Element& aOwner, const PseudoStyleRequest& aRequest) {
|
|
auto& data = GetOrCreateData(aRequest);
|
|
if (auto* collection = data.mTransitions.get()) {
|
|
return *collection;
|
|
}
|
|
return data.DoEnsureTransitions(aOwner, aRequest);
|
|
}
|
|
|
|
CSSAnimationCollection* GetAnimationCollection(
|
|
const PseudoStyleRequest& aRequest) const {
|
|
if (auto* data = GetData(aRequest)) {
|
|
return data->mAnimations.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void ClearAnimationCollectionFor(const PseudoStyleRequest& aRequest);
|
|
|
|
CSSAnimationCollection& EnsureAnimationCollection(
|
|
dom::Element& aOwner, const PseudoStyleRequest& aRequest) {
|
|
auto& data = GetOrCreateData(aRequest);
|
|
if (auto* collection = data.mAnimations.get()) {
|
|
return *collection;
|
|
}
|
|
return data.DoEnsureAnimations(aOwner, aRequest);
|
|
}
|
|
|
|
ScrollTimelineCollection* GetScrollTimelineCollection(
|
|
const PseudoStyleRequest& aRequest) const {
|
|
if (auto* data = GetData(aRequest)) {
|
|
return data->mScrollTimelines.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void ClearScrollTimelineCollectionFor(const PseudoStyleRequest& aRequest);
|
|
|
|
ScrollTimelineCollection& EnsureScrollTimelineCollection(
|
|
dom::Element& aOwner, const PseudoStyleRequest& aRequest) {
|
|
auto& data = GetOrCreateData(aRequest);
|
|
if (auto* collection = data.mScrollTimelines.get()) {
|
|
return *collection;
|
|
}
|
|
return data.DoEnsureScrollTimelines(aOwner, aRequest);
|
|
}
|
|
|
|
ViewTimelineCollection* GetViewTimelineCollection(
|
|
const PseudoStyleRequest& aRequest) const {
|
|
if (auto* data = GetData(aRequest)) {
|
|
return data->mViewTimelines.get();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void ClearViewTimelineCollectionFor(const PseudoStyleRequest& aRequest);
|
|
|
|
ViewTimelineCollection& EnsureViewTimelineCollection(
|
|
dom::Element& aOwner, const PseudoStyleRequest& aRequest) {
|
|
auto& data = GetOrCreateData(aRequest);
|
|
if (auto* collection = data.mViewTimelines.get()) {
|
|
return *collection;
|
|
}
|
|
return data.DoEnsureViewTimelines(aOwner, aRequest);
|
|
}
|
|
|
|
ElementAnimationData() = default;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif
|