Bug 1921553 - Use PseudoStyleRequest in AnimationCollection and TimelineCollection. r=view-transitions-reviewers,layout-reviewers,emilio
Just like what we do for EffectSet. Also, we will update ElementAnimationData later, so for now only change the APIs of AnimationCollection and TimelineCollection (and their callers). Differential Revision: https://phabricator.services.mozilla.com/D228227
This commit is contained in:
@@ -56,7 +56,8 @@ CSSTransitionCollection&
|
||||
ElementAnimationData::PerElementOrPseudoData::DoEnsureTransitions(
|
||||
dom::Element& aOwner, PseudoStyleType aType) {
|
||||
MOZ_ASSERT(!mTransitions);
|
||||
mTransitions = MakeUnique<CSSTransitionCollection>(aOwner, aType);
|
||||
mTransitions =
|
||||
MakeUnique<CSSTransitionCollection>(aOwner, PseudoStyleRequest(aType));
|
||||
return *mTransitions;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,8 @@ CSSAnimationCollection&
|
||||
ElementAnimationData::PerElementOrPseudoData::DoEnsureAnimations(
|
||||
dom::Element& aOwner, PseudoStyleType aType) {
|
||||
MOZ_ASSERT(!mAnimations);
|
||||
mAnimations = MakeUnique<CSSAnimationCollection>(aOwner, aType);
|
||||
mAnimations =
|
||||
MakeUnique<CSSAnimationCollection>(aOwner, PseudoStyleRequest(aType));
|
||||
return *mAnimations;
|
||||
}
|
||||
|
||||
@@ -72,7 +74,8 @@ ScrollTimelineCollection&
|
||||
ElementAnimationData::PerElementOrPseudoData::DoEnsureScrollTimelines(
|
||||
dom::Element& aOwner, PseudoStyleType aType) {
|
||||
MOZ_ASSERT(!mScrollTimelines);
|
||||
mScrollTimelines = MakeUnique<ScrollTimelineCollection>(aOwner, aType);
|
||||
mScrollTimelines =
|
||||
MakeUnique<ScrollTimelineCollection>(aOwner, PseudoStyleRequest(aType));
|
||||
return *mScrollTimelines;
|
||||
}
|
||||
|
||||
@@ -80,7 +83,8 @@ ViewTimelineCollection&
|
||||
ElementAnimationData::PerElementOrPseudoData::DoEnsureViewTimelines(
|
||||
dom::Element& aOwner, PseudoStyleType aType) {
|
||||
MOZ_ASSERT(!mViewTimelines);
|
||||
mViewTimelines = MakeUnique<ViewTimelineCollection>(aOwner, aType);
|
||||
mViewTimelines =
|
||||
MakeUnique<ViewTimelineCollection>(aOwner, PseudoStyleRequest(aType));
|
||||
return *mViewTimelines;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,10 +102,11 @@ already_AddRefed<ScrollTimeline> ScrollTimeline::MakeAnonymous(
|
||||
|
||||
/* static*/ already_AddRefed<ScrollTimeline> ScrollTimeline::MakeNamed(
|
||||
Document* aDocument, Element* aReferenceElement,
|
||||
PseudoStyleType aPseudoType, const StyleScrollTimeline& aStyleTimeline) {
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleScrollTimeline& aStyleTimeline) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
Scroller scroller = Scroller::Named(aReferenceElement, aPseudoType);
|
||||
Scroller scroller = Scroller::Named(aReferenceElement, aPseudoRequest.mType);
|
||||
return MakeAndAddRef<ScrollTimeline>(aDocument, std::move(scroller),
|
||||
aStyleTimeline.GetAxis());
|
||||
}
|
||||
@@ -188,11 +189,11 @@ bool ScrollTimeline::ScrollingDirectionIsAvailable() const {
|
||||
Axis());
|
||||
}
|
||||
|
||||
void ScrollTimeline::ReplacePropertiesWith(const Element* aReferenceElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const StyleScrollTimeline& aNew) {
|
||||
void ScrollTimeline::ReplacePropertiesWith(
|
||||
const Element* aReferenceElement, const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleScrollTimeline& aNew) {
|
||||
MOZ_ASSERT(aReferenceElement == mSource.mElement &&
|
||||
aPseudoType == mSource.mPseudoType);
|
||||
aPseudoRequest.mType == mSource.mPseudoType);
|
||||
mAxis = aNew.GetAxis();
|
||||
|
||||
for (auto* anim = mAnimationOrder.getFirst(); anim;
|
||||
@@ -219,8 +220,8 @@ void ScrollTimeline::RegisterWithScrollSource() {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& scheduler =
|
||||
ProgressTimelineScheduler::Ensure(mSource.mElement, mSource.mPseudoType);
|
||||
auto& scheduler = ProgressTimelineScheduler::Ensure(
|
||||
mSource.mElement, PseudoStyleRequest(mSource.mPseudoType));
|
||||
scheduler.AddTimeline(this);
|
||||
}
|
||||
|
||||
@@ -229,15 +230,16 @@ void ScrollTimeline::UnregisterFromScrollSource() {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* scheduler =
|
||||
ProgressTimelineScheduler::Get(mSource.mElement, mSource.mPseudoType);
|
||||
auto* scheduler = ProgressTimelineScheduler::Get(
|
||||
mSource.mElement, PseudoStyleRequest(mSource.mPseudoType));
|
||||
if (!scheduler) {
|
||||
return;
|
||||
}
|
||||
|
||||
scheduler->RemoveTimeline(this);
|
||||
if (scheduler->IsEmpty()) {
|
||||
ProgressTimelineScheduler::Destroy(mSource.mElement, mSource.mPseudoType);
|
||||
ProgressTimelineScheduler::Destroy(mSource.mElement,
|
||||
PseudoStyleRequest(mSource.mPseudoType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,29 +280,29 @@ void ScrollTimeline::NotifyAnimationContentVisibilityChanged(
|
||||
// Methods of ProgressTimelineScheduler
|
||||
// ------------------------------------
|
||||
/* static */ ProgressTimelineScheduler* ProgressTimelineScheduler::Get(
|
||||
const Element* aElement, PseudoStyleType aPseudoType) {
|
||||
const Element* aElement, const PseudoStyleRequest& aPseudoRequest) {
|
||||
MOZ_ASSERT(aElement);
|
||||
auto* data = aElement->GetAnimationData();
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return data->GetProgressTimelineScheduler(aPseudoType);
|
||||
return data->GetProgressTimelineScheduler(aPseudoRequest.mType);
|
||||
}
|
||||
|
||||
/* static */ ProgressTimelineScheduler& ProgressTimelineScheduler::Ensure(
|
||||
Element* aElement, PseudoStyleType aPseudoType) {
|
||||
Element* aElement, const PseudoStyleRequest& aPseudoRequest) {
|
||||
MOZ_ASSERT(aElement);
|
||||
return aElement->EnsureAnimationData().EnsureProgressTimelineScheduler(
|
||||
*aElement, aPseudoType);
|
||||
*aElement, aPseudoRequest.mType);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ProgressTimelineScheduler::Destroy(const Element* aElement,
|
||||
PseudoStyleType aPseudoType) {
|
||||
void ProgressTimelineScheduler::Destroy(
|
||||
const Element* aElement, const PseudoStyleRequest& aPseudoRequest) {
|
||||
auto* data = aElement->GetAnimationData();
|
||||
MOZ_ASSERT(data);
|
||||
data->ClearProgressTimelineScheduler(aPseudoType);
|
||||
data->ClearProgressTimelineScheduler(aPseudoRequest.mType);
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
@@ -120,7 +120,8 @@ class ScrollTimeline : public AnimationTimeline {
|
||||
// scroll-timeline-name property.
|
||||
static already_AddRefed<ScrollTimeline> MakeNamed(
|
||||
Document* aDocument, Element* aReferenceElement,
|
||||
PseudoStyleType aPseudoType, const StyleScrollTimeline& aStyleTimeline);
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleScrollTimeline& aStyleTimeline);
|
||||
|
||||
bool operator==(const ScrollTimeline& aOther) const {
|
||||
return mDocument == aOther.mDocument && mSource == aOther.mSource &&
|
||||
@@ -195,7 +196,7 @@ class ScrollTimeline : public AnimationTimeline {
|
||||
bool ScrollingDirectionIsAvailable() const;
|
||||
|
||||
void ReplacePropertiesWith(const Element* aReferenceElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleScrollTimeline& aNew);
|
||||
|
||||
void NotifyAnimationContentVisibilityChanged(Animation* aAnimation,
|
||||
@@ -252,11 +253,12 @@ class ProgressTimelineScheduler {
|
||||
ProgressTimelineScheduler() { MOZ_COUNT_CTOR(ProgressTimelineScheduler); }
|
||||
~ProgressTimelineScheduler() { MOZ_COUNT_DTOR(ProgressTimelineScheduler); }
|
||||
|
||||
static ProgressTimelineScheduler* Get(const Element* aElement,
|
||||
PseudoStyleType aPseudoType);
|
||||
static ProgressTimelineScheduler& Ensure(Element* aElement,
|
||||
PseudoStyleType aPseudoType);
|
||||
static void Destroy(const Element* aElement, PseudoStyleType aPseudoType);
|
||||
static ProgressTimelineScheduler* Get(
|
||||
const Element* aElement, const PseudoStyleRequest& aPseudoRequest);
|
||||
static ProgressTimelineScheduler& Ensure(
|
||||
Element* aElement, const PseudoStyleRequest& aPseudoRequest);
|
||||
static void Destroy(const Element* aElement,
|
||||
const PseudoStyleRequest& aPseudoRequest);
|
||||
|
||||
void AddTimeline(ScrollTimeline* aScrollTimeline) {
|
||||
Unused << mTimelines.put(aScrollTimeline);
|
||||
|
||||
@@ -18,21 +18,21 @@ NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ViewTimeline, ScrollTimeline)
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ViewTimeline> ViewTimeline::MakeNamed(
|
||||
Document* aDocument, Element* aSubject, PseudoStyleType aPseudoType,
|
||||
Document* aDocument, Element* aSubject,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleViewTimeline& aStyleTimeline) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// 1. Lookup scroller. We have to find the nearest scroller from |aSubject|
|
||||
// and |aPseudoType|.
|
||||
auto [element, pseudo] =
|
||||
FindNearestScroller(aSubject, PseudoStyleRequest(aPseudoType));
|
||||
auto [element, pseudo] = FindNearestScroller(aSubject, aPseudoRequest);
|
||||
auto scroller =
|
||||
Scroller::Nearest(const_cast<Element*>(element), pseudo.mType);
|
||||
|
||||
// 2. Create timeline.
|
||||
return MakeAndAddRef<ViewTimeline>(aDocument, scroller,
|
||||
aStyleTimeline.GetAxis(), aSubject,
|
||||
aPseudoType, aStyleTimeline.GetInset());
|
||||
return MakeAndAddRef<ViewTimeline>(
|
||||
aDocument, scroller, aStyleTimeline.GetAxis(), aSubject,
|
||||
aPseudoRequest.mType, aStyleTimeline.GetInset());
|
||||
}
|
||||
|
||||
/* static */
|
||||
@@ -49,11 +49,11 @@ already_AddRefed<ViewTimeline> ViewTimeline::MakeAnonymous(
|
||||
aTarget.mPseudoRequest.mType, aInset);
|
||||
}
|
||||
|
||||
void ViewTimeline::ReplacePropertiesWith(Element* aSubjectElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const StyleViewTimeline& aNew) {
|
||||
void ViewTimeline::ReplacePropertiesWith(
|
||||
Element* aSubjectElement, const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleViewTimeline& aNew) {
|
||||
mSubject = aSubjectElement;
|
||||
mSubjectPseudoType = aPseudoType;
|
||||
mSubjectPseudoType = aPseudoRequest.mType;
|
||||
mAxis = aNew.GetAxis();
|
||||
// FIXME: Bug 1817073. We assume it is a non-animatable value for now.
|
||||
mInset = aNew.GetInset();
|
||||
|
||||
@@ -34,7 +34,8 @@ class ViewTimeline final : public ScrollTimeline {
|
||||
// Note: |aSubject| is used as the subject which specifies view-timeline-name
|
||||
// property, and we use this subject to look up its nearest scroll container.
|
||||
static already_AddRefed<ViewTimeline> MakeNamed(
|
||||
Document* aDocument, Element* aSubject, PseudoStyleType aPseudoType,
|
||||
Document* aDocument, Element* aSubject,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleViewTimeline& aStyleTimeline);
|
||||
|
||||
static already_AddRefed<ViewTimeline> MakeAnonymous(
|
||||
@@ -49,7 +50,7 @@ class ViewTimeline final : public ScrollTimeline {
|
||||
bool IsViewTimeline() const override { return true; }
|
||||
|
||||
void ReplacePropertiesWith(Element* aSubjectElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const StyleViewTimeline& aNew);
|
||||
|
||||
private:
|
||||
|
||||
@@ -2106,8 +2106,8 @@ void RestyleManager::AnimationsWithDestroyedFrame ::StopAnimationsWithoutFrame(
|
||||
|
||||
// FIXME: Bug 1922095. Revisit here to make sure we destroy the view
|
||||
// transitions if the associated frames are destroyed.
|
||||
animationManager->StopAnimationsForElement(element, aPseudoRequest.mType);
|
||||
transitionManager->StopAnimationsForElement(element, aPseudoRequest.mType);
|
||||
animationManager->StopAnimationsForElement(element, aPseudoRequest);
|
||||
transitionManager->StopAnimationsForElement(element, aPseudoRequest);
|
||||
|
||||
// All other animations should keep running but not running on the
|
||||
// *compositor* at this point.
|
||||
|
||||
@@ -8065,12 +8065,9 @@ void ScrollContainerFrame::ScheduleScrollAnimations() {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: We will tweak ProgressTimelineScheduler::Get() to handle
|
||||
// PseudoStyleRequest better in the following patches.
|
||||
const auto [element, request] =
|
||||
AnimationUtils::GetElementPseudoPair(elementOrPseudo);
|
||||
const auto* scheduler =
|
||||
ProgressTimelineScheduler::Get(element, request.mType);
|
||||
const auto* scheduler = ProgressTimelineScheduler::Get(element, request);
|
||||
if (!scheduler) {
|
||||
// We don't have scroll timelines associated with this frame.
|
||||
return;
|
||||
|
||||
@@ -37,25 +37,25 @@ void AnimationCollection<AnimationType>::Destroy() {
|
||||
auto* data = mElement.GetAnimationData();
|
||||
MOZ_ASSERT(data);
|
||||
if constexpr (std::is_same_v<AnimationType, dom::CSSAnimation>) {
|
||||
MOZ_ASSERT(data->GetAnimationCollection(mPseudo) == this);
|
||||
data->ClearAnimationCollectionFor(mPseudo);
|
||||
MOZ_ASSERT(data->GetAnimationCollection(mPseudo.mType) == this);
|
||||
data->ClearAnimationCollectionFor(mPseudo.mType);
|
||||
} else {
|
||||
MOZ_ASSERT(data->GetTransitionCollection(mPseudo) == this);
|
||||
data->ClearTransitionCollectionFor(mPseudo);
|
||||
MOZ_ASSERT(data->GetTransitionCollection(mPseudo.mType) == this);
|
||||
data->ClearTransitionCollectionFor(mPseudo.mType);
|
||||
}
|
||||
}
|
||||
|
||||
template <class AnimationType>
|
||||
AnimationCollection<AnimationType>* AnimationCollection<AnimationType>::Get(
|
||||
const dom::Element* aElement, const PseudoStyleType aType) {
|
||||
const dom::Element* aElement, const PseudoStyleRequest& aRequest) {
|
||||
auto* data = aElement->GetAnimationData();
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
if constexpr (std::is_same_v<AnimationType, dom::CSSAnimation>) {
|
||||
return data->GetAnimationCollection(aType);
|
||||
return data->GetAnimationCollection(aRequest.mType);
|
||||
} else {
|
||||
return data->GetTransitionCollection(aType);
|
||||
return data->GetTransitionCollection(aRequest.mType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ AnimationCollection<AnimationType>::Get(const nsIFrame* aFrame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Get(target->mElement, target->mPseudoRequest.mType);
|
||||
return Get(target->mElement, target->mPseudoRequest);
|
||||
}
|
||||
|
||||
// Explicit class instantiations
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/PseudoStyleType.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
@@ -21,7 +22,6 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
}
|
||||
enum class PseudoStyleType : uint8_t;
|
||||
|
||||
template <class AnimationType>
|
||||
class AnimationCollection
|
||||
@@ -29,8 +29,9 @@ class AnimationCollection
|
||||
typedef AnimationCollection<AnimationType> SelfType;
|
||||
|
||||
public:
|
||||
AnimationCollection(dom::Element& aOwner, PseudoStyleType aPseudoType)
|
||||
: mElement(aOwner), mPseudo(aPseudoType) {
|
||||
AnimationCollection(dom::Element& aOwner,
|
||||
const PseudoStyleRequest& aPseudoRequest)
|
||||
: mElement(aOwner), mPseudo(aPseudoRequest) {
|
||||
MOZ_COUNT_CTOR(AnimationCollection);
|
||||
}
|
||||
|
||||
@@ -44,13 +45,13 @@ class AnimationCollection
|
||||
// animations.
|
||||
static AnimationCollection* Get(const nsIFrame* aFrame);
|
||||
static AnimationCollection* Get(const dom::Element* aElement,
|
||||
PseudoStyleType aPseudoType);
|
||||
const PseudoStyleRequest& aPseudoRequest);
|
||||
|
||||
// The element. Weak reference is fine since it owns us.
|
||||
// FIXME(emilio): These are only needed for Destroy(), so maybe remove and
|
||||
// rely on the caller clearing us properly?
|
||||
dom::Element& mElement;
|
||||
const PseudoStyleType mPseudo;
|
||||
const PseudoStyleRequest mPseudo;
|
||||
|
||||
nsTArray<RefPtr<AnimationType>> mAnimations;
|
||||
|
||||
|
||||
@@ -52,10 +52,10 @@ class CommonAnimationManager {
|
||||
* ::before, ::after and ::marker.
|
||||
*/
|
||||
void StopAnimationsForElement(dom::Element* aElement,
|
||||
PseudoStyleType aPseudoType) {
|
||||
const PseudoStyleRequest& aPseudoRequest) {
|
||||
MOZ_ASSERT(aElement);
|
||||
auto* collection =
|
||||
AnimationCollection<AnimationType>::Get(aElement, aPseudoType);
|
||||
AnimationCollection<AnimationType>::Get(aElement, aPseudoRequest);
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -542,19 +542,19 @@ void Gecko_UpdateAnimations(const Element* aElement,
|
||||
// timeline defined by itself.
|
||||
if (aTasks & UpdateAnimationsTasks::ScrollTimelines) {
|
||||
presContext->TimelineManager()->UpdateTimelines(
|
||||
const_cast<Element*>(element), pseudoRequest.mType, aComputedData,
|
||||
const_cast<Element*>(element), pseudoRequest, aComputedData,
|
||||
TimelineManager::ProgressTimelineType::Scroll);
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::ViewTimelines) {
|
||||
presContext->TimelineManager()->UpdateTimelines(
|
||||
const_cast<Element*>(element), pseudoRequest.mType, aComputedData,
|
||||
const_cast<Element*>(element), pseudoRequest, aComputedData,
|
||||
TimelineManager::ProgressTimelineType::View);
|
||||
}
|
||||
|
||||
if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
|
||||
presContext->AnimationManager()->UpdateAnimations(
|
||||
const_cast<Element*>(element), pseudoRequest.mType, aComputedData);
|
||||
const_cast<Element*>(element), pseudoRequest, aComputedData);
|
||||
}
|
||||
|
||||
// aComputedData might be nullptr if the target element is now in a
|
||||
@@ -619,21 +619,21 @@ bool Gecko_ElementHasAnimations(const Element* aElement) {
|
||||
bool Gecko_ElementHasCSSAnimations(const Element* aElement) {
|
||||
const auto [element, pseudo] = AnimationUtils::GetElementPseudoPair(aElement);
|
||||
auto* collection =
|
||||
nsAnimationManager::CSSAnimationCollection::Get(element, pseudo.mType);
|
||||
nsAnimationManager::CSSAnimationCollection::Get(element, pseudo);
|
||||
return collection && !collection->mAnimations.IsEmpty();
|
||||
}
|
||||
|
||||
bool Gecko_ElementHasCSSTransitions(const Element* aElement) {
|
||||
const auto [element, pseudo] = AnimationUtils::GetElementPseudoPair(aElement);
|
||||
auto* collection =
|
||||
nsTransitionManager::CSSTransitionCollection::Get(element, pseudo.mType);
|
||||
nsTransitionManager::CSSTransitionCollection::Get(element, pseudo);
|
||||
return collection && !collection->mAnimations.IsEmpty();
|
||||
}
|
||||
|
||||
size_t Gecko_ElementTransitions_Length(const Element* aElement) {
|
||||
const auto [element, pseudo] = AnimationUtils::GetElementPseudoPair(aElement);
|
||||
auto* collection =
|
||||
nsTransitionManager::CSSTransitionCollection::Get(element, pseudo.mType);
|
||||
nsTransitionManager::CSSTransitionCollection::Get(element, pseudo);
|
||||
return collection ? collection->mAnimations.Length() : 0;
|
||||
}
|
||||
|
||||
@@ -641,7 +641,7 @@ static CSSTransition* GetCurrentTransitionAt(const Element* aElement,
|
||||
size_t aIndex) {
|
||||
const auto [element, pseudo] = AnimationUtils::GetElementPseudoPair(aElement);
|
||||
auto* collection =
|
||||
nsTransitionManager::CSSTransitionCollection ::Get(element, pseudo.mType);
|
||||
nsTransitionManager::CSSTransitionCollection ::Get(element, pseudo);
|
||||
if (!collection) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ void TimelineCollection<TimelineType>::Destroy() {
|
||||
auto* data = mElement.GetAnimationData();
|
||||
MOZ_ASSERT(data);
|
||||
if constexpr (std::is_same_v<TimelineType, dom::ScrollTimeline>) {
|
||||
MOZ_ASSERT(data->GetScrollTimelineCollection(mPseudo) == this);
|
||||
data->ClearScrollTimelineCollectionFor(mPseudo);
|
||||
MOZ_ASSERT(data->GetScrollTimelineCollection(mPseudo.mType) == this);
|
||||
data->ClearScrollTimelineCollectionFor(mPseudo.mType);
|
||||
} else if constexpr (std::is_same_v<TimelineType, dom::ViewTimeline>) {
|
||||
MOZ_ASSERT(data->GetViewTimelineCollection(mPseudo) == this);
|
||||
data->ClearViewTimelineCollectionFor(mPseudo);
|
||||
MOZ_ASSERT(data->GetViewTimelineCollection(mPseudo.mType) == this);
|
||||
data->ClearViewTimelineCollectionFor(mPseudo.mType);
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("Unsupported TimelienType");
|
||||
}
|
||||
@@ -41,8 +41,8 @@ void TimelineCollection<TimelineType>::Destroy() {
|
||||
|
||||
template <class TimelineType>
|
||||
/* static */ TimelineCollection<TimelineType>*
|
||||
TimelineCollection<TimelineType>::Get(const dom::Element* aElement,
|
||||
const PseudoStyleType aPseudoType) {
|
||||
TimelineCollection<TimelineType>::Get(
|
||||
const dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest) {
|
||||
MOZ_ASSERT(aElement);
|
||||
auto* data = aElement->GetAnimationData();
|
||||
if (!data) {
|
||||
@@ -50,11 +50,11 @@ TimelineCollection<TimelineType>::Get(const dom::Element* aElement,
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<TimelineType, dom::ScrollTimeline>) {
|
||||
return data->GetScrollTimelineCollection(aPseudoType);
|
||||
return data->GetScrollTimelineCollection(aPseudoRequest.mType);
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<TimelineType, dom::ViewTimeline>) {
|
||||
return data->GetViewTimelineCollection(aPseudoType);
|
||||
return data->GetViewTimelineCollection(aPseudoRequest.mType);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/PseudoStyleType.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsAtomHashKeys.h"
|
||||
#include "nsTHashMap.h"
|
||||
@@ -20,7 +21,6 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
}
|
||||
enum class PseudoStyleType : uint8_t;
|
||||
|
||||
// The collection of ScrollTimeline or ViewTimeline. We use the template class
|
||||
// to share the implementation for these two timeline types.
|
||||
@@ -31,8 +31,9 @@ class TimelineCollection final
|
||||
using SelfType = TimelineCollection<TimelineType>;
|
||||
using TimelineMap = nsTHashMap<RefPtr<nsAtom>, RefPtr<TimelineType>>;
|
||||
|
||||
TimelineCollection(dom::Element& aElement, PseudoStyleType aPseudoType)
|
||||
: mElement(aElement), mPseudo(aPseudoType) {
|
||||
TimelineCollection(dom::Element& aElement,
|
||||
const PseudoStyleRequest& aPseudoRequest)
|
||||
: mElement(aElement), mPseudo(aPseudoRequest) {
|
||||
MOZ_COUNT_CTOR(TimelineCollection);
|
||||
}
|
||||
|
||||
@@ -54,13 +55,13 @@ class TimelineCollection final
|
||||
// Get the collection of timelines for the given |aElement| and or create it
|
||||
// if it does not already exist.
|
||||
static TimelineCollection* Get(const dom::Element* aElement,
|
||||
PseudoStyleType aPseudoType);
|
||||
const PseudoStyleRequest& aPseudoRequest);
|
||||
const TimelineMap& Timelines() const { return mTimelines; }
|
||||
|
||||
private:
|
||||
// The element. Weak reference is fine since it owns us.
|
||||
dom::Element& mElement;
|
||||
const PseudoStyleType mPseudo;
|
||||
const PseudoStyleRequest mPseudo;
|
||||
|
||||
TimelineMap mTimelines;
|
||||
};
|
||||
|
||||
@@ -18,9 +18,10 @@ using dom::ScrollTimeline;
|
||||
using dom::ViewTimeline;
|
||||
|
||||
template <typename TimelineType>
|
||||
void TryDestroyTimeline(Element* aElement, PseudoStyleType aPseudoType) {
|
||||
static void TryDestroyTimeline(Element* aElement,
|
||||
const PseudoStyleRequest& aPseudoRequest) {
|
||||
auto* collection =
|
||||
TimelineCollection<TimelineType>::Get(aElement, aPseudoType);
|
||||
TimelineCollection<TimelineType>::Get(aElement, aPseudoRequest);
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
@@ -28,7 +29,7 @@ void TryDestroyTimeline(Element* aElement, PseudoStyleType aPseudoType) {
|
||||
}
|
||||
|
||||
void TimelineManager::UpdateTimelines(Element* aElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const ComputedStyle* aComputedStyle,
|
||||
ProgressTimelineType aType) {
|
||||
MOZ_ASSERT(
|
||||
@@ -46,22 +47,22 @@ void TimelineManager::UpdateTimelines(Element* aElement,
|
||||
switch (aType) {
|
||||
case ProgressTimelineType::Scroll:
|
||||
if (shouldDestroyTimelines) {
|
||||
TryDestroyTimeline<ScrollTimeline>(aElement, aPseudoType);
|
||||
TryDestroyTimeline<ScrollTimeline>(aElement, aPseudoRequest);
|
||||
return;
|
||||
}
|
||||
DoUpdateTimelines<StyleScrollTimeline, ScrollTimeline>(
|
||||
mPresContext, aElement, aPseudoType,
|
||||
mPresContext, aElement, aPseudoRequest,
|
||||
aComputedStyle->StyleUIReset()->mScrollTimelines,
|
||||
aComputedStyle->StyleUIReset()->mScrollTimelineNameCount);
|
||||
break;
|
||||
|
||||
case ProgressTimelineType::View:
|
||||
if (shouldDestroyTimelines) {
|
||||
TryDestroyTimeline<ViewTimeline>(aElement, aPseudoType);
|
||||
TryDestroyTimeline<ViewTimeline>(aElement, aPseudoRequest);
|
||||
return;
|
||||
}
|
||||
DoUpdateTimelines<StyleViewTimeline, ViewTimeline>(
|
||||
mPresContext, aElement, aPseudoType,
|
||||
mPresContext, aElement, aPseudoRequest,
|
||||
aComputedStyle->StyleUIReset()->mViewTimelines,
|
||||
aComputedStyle->StyleUIReset()->mViewTimelineNameCount);
|
||||
break;
|
||||
@@ -79,7 +80,7 @@ static already_AddRefed<TimelineType> PopExistingTimeline(
|
||||
|
||||
template <typename StyleType, typename TimelineType>
|
||||
static auto BuildTimelines(nsPresContext* aPresContext, Element* aElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const nsStyleAutoArray<StyleType>& aTimelines,
|
||||
size_t aTimelineCount,
|
||||
TimelineCollection<TimelineType>* aCollection) {
|
||||
@@ -97,10 +98,10 @@ static auto BuildTimelines(nsPresContext* aPresContext, Element* aElement,
|
||||
RefPtr<TimelineType> dest =
|
||||
PopExistingTimeline(timeline.GetName(), aCollection);
|
||||
if (dest) {
|
||||
dest->ReplacePropertiesWith(aElement, aPseudoType, timeline);
|
||||
dest->ReplacePropertiesWith(aElement, aPseudoRequest, timeline);
|
||||
} else {
|
||||
dest = TimelineType::MakeNamed(aPresContext->Document(), aElement,
|
||||
aPseudoType, timeline);
|
||||
aPseudoRequest, timeline);
|
||||
}
|
||||
MOZ_ASSERT(dest);
|
||||
|
||||
@@ -130,10 +131,11 @@ ViewTimelineCollection& EnsureTimelineCollection<ViewTimeline>(
|
||||
|
||||
template <typename StyleType, typename TimelineType>
|
||||
void TimelineManager::DoUpdateTimelines(
|
||||
nsPresContext* aPresContext, Element* aElement, PseudoStyleType aPseudoType,
|
||||
nsPresContext* aPresContext, Element* aElement,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const nsStyleAutoArray<StyleType>& aStyleTimelines, size_t aTimelineCount) {
|
||||
auto* collection =
|
||||
TimelineCollection<TimelineType>::Get(aElement, aPseudoType);
|
||||
TimelineCollection<TimelineType>::Get(aElement, aPseudoRequest);
|
||||
if (!collection && aTimelineCount == 1 &&
|
||||
aStyleTimelines[0].GetName() == nsGkAtoms::_empty) {
|
||||
return;
|
||||
@@ -142,7 +144,7 @@ void TimelineManager::DoUpdateTimelines(
|
||||
// We create a new timeline list based on its computed style and the existing
|
||||
// timelines.
|
||||
auto newTimelines = BuildTimelines<StyleType, TimelineType>(
|
||||
aPresContext, aElement, aPseudoType, aStyleTimelines, aTimelineCount,
|
||||
aPresContext, aElement, aPseudoRequest, aStyleTimelines, aTimelineCount,
|
||||
collection);
|
||||
|
||||
if (newTimelines.IsEmpty()) {
|
||||
@@ -153,8 +155,8 @@ void TimelineManager::DoUpdateTimelines(
|
||||
}
|
||||
|
||||
if (!collection) {
|
||||
collection =
|
||||
&EnsureTimelineCollection<TimelineType>(*aElement, aPseudoType);
|
||||
collection = &EnsureTimelineCollection<TimelineType>(*aElement,
|
||||
aPseudoRequest.mType);
|
||||
if (!collection->isInList()) {
|
||||
AddTimelineCollection(collection);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class nsPresContext;
|
||||
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
enum class PseudoStyleType : uint8_t;
|
||||
struct PseudoStyleRequest;
|
||||
|
||||
namespace dom {
|
||||
class Element;
|
||||
@@ -47,7 +47,8 @@ class TimelineManager {
|
||||
Scroll,
|
||||
View,
|
||||
};
|
||||
void UpdateTimelines(dom::Element* aElement, PseudoStyleType aPseudoType,
|
||||
void UpdateTimelines(dom::Element* aElement,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const ComputedStyle* aComputedStyle,
|
||||
ProgressTimelineType aType);
|
||||
|
||||
@@ -56,7 +57,7 @@ class TimelineManager {
|
||||
private:
|
||||
template <typename StyleType, typename TimelineType>
|
||||
void DoUpdateTimelines(nsPresContext* aPresContext, dom::Element* aElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const PseudoStyleRequest& aPseudoRequest,
|
||||
const nsStyleAutoArray<StyleType>& aStyleTimelines,
|
||||
size_t aTimelineCount);
|
||||
|
||||
|
||||
@@ -230,17 +230,15 @@ static already_AddRefed<dom::AnimationTimeline> GetNamedProgressTimeline(
|
||||
// In case of a name conflict on the same element, scroll progress
|
||||
// timelines take precedence over view progress timelines.
|
||||
const auto [element, pseudo] = AnimationUtils::GetElementPseudoPair(e);
|
||||
// TODO: Tweak TimelineCollection to handle PseudoStyleRequest well in the
|
||||
// following patches.
|
||||
if (auto* collection =
|
||||
TimelineCollection<ScrollTimeline>::Get(element, pseudo.mType)) {
|
||||
TimelineCollection<ScrollTimeline>::Get(element, pseudo)) {
|
||||
if (RefPtr<ScrollTimeline> timeline = collection->Lookup(aName)) {
|
||||
return timeline.forget();
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* collection =
|
||||
TimelineCollection<ViewTimeline>::Get(element, pseudo.mType)) {
|
||||
TimelineCollection<ViewTimeline>::Get(element, pseudo)) {
|
||||
if (RefPtr<ViewTimeline> timeline = collection->Lookup(aName)) {
|
||||
return timeline.forget();
|
||||
}
|
||||
@@ -394,9 +392,9 @@ static nsAnimationManager::OwningCSSAnimationPtrArray BuildAnimations(
|
||||
return result;
|
||||
}
|
||||
|
||||
void nsAnimationManager::UpdateAnimations(dom::Element* aElement,
|
||||
PseudoStyleType aPseudoType,
|
||||
const ComputedStyle* aComputedStyle) {
|
||||
void nsAnimationManager::UpdateAnimations(
|
||||
dom::Element* aElement, const PseudoStyleRequest& aPseudoRequest,
|
||||
const ComputedStyle* aComputedStyle) {
|
||||
MOZ_ASSERT(mPresContext->IsDynamic(),
|
||||
"Should not update animations for print or print preview");
|
||||
MOZ_ASSERT(aElement->IsInComposedDoc(),
|
||||
@@ -411,11 +409,11 @@ void nsAnimationManager::UpdateAnimations(dom::Element* aElement,
|
||||
// In either case, since CSS animations should not run in display:none
|
||||
// subtrees we should stop (actually, destroy) any animations on this
|
||||
// element here.
|
||||
StopAnimationsForElement(aElement, aPseudoType);
|
||||
StopAnimationsForElement(aElement, aPseudoRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
NonOwningAnimationTarget target(aElement, PseudoStyleRequest(aPseudoType));
|
||||
NonOwningAnimationTarget target(aElement, aPseudoRequest);
|
||||
ServoCSSAnimationBuilder builder(aComputedStyle);
|
||||
|
||||
DoUpdateAnimations(target, *aComputedStyle->StyleUIReset(), builder);
|
||||
@@ -429,8 +427,8 @@ void nsAnimationManager::DoUpdateAnimations(
|
||||
// Likewise, when we initially construct frames, we're not in a
|
||||
// style change, but also not in an animation restyle.
|
||||
|
||||
auto* collection = CSSAnimationCollection::Get(aTarget.mElement,
|
||||
aTarget.mPseudoRequest.mType);
|
||||
auto* collection =
|
||||
CSSAnimationCollection::Get(aTarget.mElement, aTarget.mPseudoRequest);
|
||||
if (!collection && aStyle.mAnimationNameCount == 1 &&
|
||||
aStyle.mAnimations[0].GetName() == nsGkAtoms::_empty) {
|
||||
return;
|
||||
|
||||
@@ -21,8 +21,8 @@ struct nsStyleUIReset;
|
||||
namespace mozilla {
|
||||
class ComputedStyle;
|
||||
|
||||
enum class PseudoStyleType : uint8_t;
|
||||
struct NonOwningAnimationTarget;
|
||||
struct PseudoStyleRequest;
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
@@ -45,7 +45,7 @@ class nsAnimationManager final
|
||||
* but with servo's computed values.
|
||||
*/
|
||||
void UpdateAnimations(mozilla::dom::Element* aElement,
|
||||
mozilla::PseudoStyleType aPseudoType,
|
||||
const mozilla::PseudoStyleRequest& aPseudoRequest,
|
||||
const mozilla::ComputedStyle* aComputedValues);
|
||||
|
||||
// Utility function to walk through |aIter| to find the Keyframe with
|
||||
|
||||
@@ -49,11 +49,12 @@ bool nsTransitionManager::UpdateTransitions(dom::Element* aElement,
|
||||
|
||||
MOZ_ASSERT(mPresContext->IsDynamic());
|
||||
if (aNewStyle.StyleDisplay()->mDisplay == StyleDisplay::None) {
|
||||
StopAnimationsForElement(aElement, aPseudoType);
|
||||
StopAnimationsForElement(aElement, PseudoStyleRequest(aPseudoType));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* collection = CSSTransitionCollection::Get(aElement, aPseudoType);
|
||||
auto* collection =
|
||||
CSSTransitionCollection::Get(aElement, PseudoStyleRequest(aPseudoType));
|
||||
return DoUpdateTransitions(*aNewStyle.StyleUIReset(), aElement, aPseudoType,
|
||||
collection, aOldStyle, aNewStyle);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user