/* 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_TimelineManager_h #define mozilla_TimelineManager_h #include "mozilla/Assertions.h" #include "mozilla/LinkedList.h" #include "mozilla/RefPtr.h" #include "mozilla/TimelineCollection.h" #include "nsStyleAutoArray.h" #include "nsStyleStruct.h" class nsPresContext; namespace mozilla { class ComputedStyle; struct PseudoStyleRequest; namespace dom { class Element; class AnimationTimeline; class ScrollTimeline; class ViewTimeline; } // namespace dom class TimelineManager { public: explicit TimelineManager(nsPresContext* aPresContext); ~TimelineManager() { MOZ_ASSERT(!mPresContext, "Disconnect should have been called"); } void Disconnect() { mScrollTimelineNameMap.Clear(); while (auto* head = mScrollTimelineCollections.getFirst()) { head->Destroy(); } mViewTimelineNameMap.Clear(); while (auto* head = mViewTimelineCollections.getFirst()) { head->Destroy(); } mPresContext = nullptr; } enum class ProgressTimelineType : uint8_t { Scroll, View, }; void UpdateTimelines(dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest, const ComputedStyle* aComputedStyle, ProgressTimelineType aType); void UpdateTimelineScopes(const dom::Element* aElement, const ComputedStyle* aComputedStyle); Maybe> GetScopedTimeline( const dom::Element* aScopeElement, const nsAtom* aName) const; private: template using Timelines = nsTArray>; // Mapping from timeline names to timelines of that name. Depending on // the use of `timeline-scope`, may or may not be visible from the // element specifying `animation-timeline`. template using TimelineNameMap = nsTHashMap, Timelines>; template using TimelineTargetsIter = TimelineManager::Timelines::const_iterator; struct TimelineScopeEntry { RefPtr mElement; nsTArray> mNames; }; const TimelineScopeEntry* GetTimelineScope(const dom::Element* aScopeElement, const nsAtom* aName) const; template TimelineType* DoGetScopedTimeline( const dom::Element* aScopeElement, const nsAtom* aName, const TimelineNameMap& aTimelineNameMap, bool& aDuplicateFound) const; // TODO(dshin, bug 2021326): Depending on general usage, this may end up being // a hashmap. using TimelineScopes = nsTArray; template void DoUpdateTimelines(nsPresContext* aPresContext, dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest, const nsStyleAutoArray& aStyleTimelines, size_t aTimelineCount, TimelineNameMap& aTimelineNameMap); template void AddTimelineCollection(TimelineCollection* aCollection); // Find a timeline target in the given timeline collection matching // the (pseudo) element. template static TimelineTargetsIter FindInTimelineTargets( Timelines& aTimelineTargets, const dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest); // Remove given (pseudo) element's named timeline from the name map. template static void RemoveTimelineTargetByName( const nsAtom* aName, const dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest, TimelineNameMap& aTimelineNameMap); // Destroy all timelines relating to the given (pseudo) element. template static void TryDestroyTimeline( dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest, TimelineNameMap& aTimelineNameMap); #ifdef DEBUG // Assert that we do not have a timeline target for the given (pseudo) element // in the given range. template static void EnsureNoTimelineTarget( const TimelineTargetsIter& aStart, const TimelineTargetsIter& aEnd, const dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest); #endif LinkedList> mScrollTimelineCollections; // Map containing all named scroll timelines, keyed by their names. TimelineNameMap mScrollTimelineNameMap; LinkedList> mViewTimelineCollections; // Map containing all named view timelines, keyed by their names. TimelineNameMap mViewTimelineNameMap; TimelineScopes mTimelineScopes; nsPresContext* mPresContext; }; template <> inline void TimelineManager::AddTimelineCollection( TimelineCollection* aCollection) { mScrollTimelineCollections.insertBack(aCollection); } template <> inline void TimelineManager::AddTimelineCollection( TimelineCollection* aCollection) { mViewTimelineCollections.insertBack(aCollection); } } // namespace mozilla #endif // mozilla_TimelineManager_h