forked from mirrors/gecko-dev
		
	And drop an unnecessary forward declaration for nsIFrame from AnimationCommon.h. MozReview-Commit-ID: IYroCrg1rtq --HG-- extra : rebase_source : f41fc19e2cff4ef0dba26192b2f19edfb57189d6
		
			
				
	
	
		
			207 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | 
						|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | 
						|
/* 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_css_AnimationCommon_h
 | 
						|
#define mozilla_css_AnimationCommon_h
 | 
						|
 | 
						|
#include "mozilla/AnimationCollection.h"
 | 
						|
#include "mozilla/LinkedList.h"
 | 
						|
#include "mozilla/dom/Animation.h"
 | 
						|
#include "mozilla/Attributes.h" // For MOZ_NON_OWNING_REF
 | 
						|
#include "mozilla/Assertions.h"
 | 
						|
#include "mozilla/TimingParams.h"
 | 
						|
#include "mozilla/dom/Nullable.h"
 | 
						|
#include "nsContentUtils.h"
 | 
						|
 | 
						|
class nsPresContext;
 | 
						|
 | 
						|
namespace mozilla {
 | 
						|
enum class CSSPseudoElementType : uint8_t;
 | 
						|
 | 
						|
namespace dom {
 | 
						|
class Element;
 | 
						|
}
 | 
						|
 | 
						|
template <class AnimationType>
 | 
						|
class CommonAnimationManager {
 | 
						|
public:
 | 
						|
  explicit CommonAnimationManager(nsPresContext *aPresContext)
 | 
						|
    : mPresContext(aPresContext)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  // NOTE:  This can return null after Disconnect().
 | 
						|
  nsPresContext* PresContext() const { return mPresContext; }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Notify the manager that the pres context is going away.
 | 
						|
   */
 | 
						|
  void Disconnect()
 | 
						|
  {
 | 
						|
    // Content nodes might outlive the transition or animation manager.
 | 
						|
    RemoveAllElementCollections();
 | 
						|
 | 
						|
    mPresContext = nullptr;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Stop animations on the element. This method takes the real element
 | 
						|
   * rather than the element for the generated content for animations on
 | 
						|
   * ::before and ::after.
 | 
						|
   */
 | 
						|
  void StopAnimationsForElement(dom::Element* aElement,
 | 
						|
                                CSSPseudoElementType aPseudoType)
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(aElement);
 | 
						|
    AnimationCollection<AnimationType>* collection =
 | 
						|
      AnimationCollection<AnimationType>::GetAnimationCollection(aElement,
 | 
						|
                                                                 aPseudoType);
 | 
						|
    if (!collection) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
 | 
						|
    collection->Destroy();
 | 
						|
  }
 | 
						|
 | 
						|
protected:
 | 
						|
  virtual ~CommonAnimationManager()
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(!mPresContext, "Disconnect should have been called");
 | 
						|
  }
 | 
						|
 | 
						|
  void AddElementCollection(AnimationCollection<AnimationType>* aCollection)
 | 
						|
  {
 | 
						|
    mElementCollections.insertBack(aCollection);
 | 
						|
  }
 | 
						|
  void RemoveAllElementCollections()
 | 
						|
  {
 | 
						|
    while (AnimationCollection<AnimationType>* head =
 | 
						|
           mElementCollections.getFirst()) {
 | 
						|
      head->Destroy(); // Note: this removes 'head' from mElementCollections.
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  LinkedList<AnimationCollection<AnimationType>> mElementCollections;
 | 
						|
  nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Utility class for referencing the element that created a CSS animation or
 | 
						|
 * transition. It is non-owning (i.e. it uses a raw pointer) since it is only
 | 
						|
 * expected to be set by the owned animation while it actually being managed
 | 
						|
 * by the owning element.
 | 
						|
 *
 | 
						|
 * This class also abstracts the comparison of an element/pseudo-class pair
 | 
						|
 * for the sake of composite ordering since this logic is common to both CSS
 | 
						|
 * animations and transitions.
 | 
						|
 *
 | 
						|
 * (We call this OwningElementRef instead of just OwningElement so that we can
 | 
						|
 * call the getter on CSSAnimation/CSSTransition OwningElement() without
 | 
						|
 * clashing with this object's contructor.)
 | 
						|
 */
 | 
						|
class OwningElementRef final
 | 
						|
{
 | 
						|
public:
 | 
						|
  OwningElementRef() = default;
 | 
						|
 | 
						|
  explicit OwningElementRef(const NonOwningAnimationTarget& aTarget)
 | 
						|
    : mTarget(aTarget)
 | 
						|
  { }
 | 
						|
 | 
						|
  OwningElementRef(dom::Element& aElement,
 | 
						|
                   CSSPseudoElementType aPseudoType)
 | 
						|
    : mTarget(&aElement, aPseudoType)
 | 
						|
  { }
 | 
						|
 | 
						|
  bool Equals(const OwningElementRef& aOther) const
 | 
						|
  {
 | 
						|
    return mTarget == aOther.mTarget;
 | 
						|
  }
 | 
						|
 | 
						|
  bool LessThan(const OwningElementRef& aOther) const
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(mTarget.mElement && aOther.mTarget.mElement,
 | 
						|
               "Elements to compare should not be null");
 | 
						|
 | 
						|
    if (mTarget.mElement != aOther.mTarget.mElement) {
 | 
						|
      return nsContentUtils::PositionIsBefore(mTarget.mElement,
 | 
						|
                                              aOther.mTarget.mElement);
 | 
						|
    }
 | 
						|
 | 
						|
    return mTarget.mPseudoType == CSSPseudoElementType::NotPseudo ||
 | 
						|
          (mTarget.mPseudoType == CSSPseudoElementType::before &&
 | 
						|
           aOther.mTarget.mPseudoType == CSSPseudoElementType::after);
 | 
						|
  }
 | 
						|
 | 
						|
  bool IsSet() const { return !!mTarget.mElement; }
 | 
						|
 | 
						|
  void GetElement(dom::Element*& aElement,
 | 
						|
                  CSSPseudoElementType& aPseudoType) const
 | 
						|
  {
 | 
						|
    aElement = mTarget.mElement;
 | 
						|
    aPseudoType = mTarget.mPseudoType;
 | 
						|
  }
 | 
						|
 | 
						|
  const NonOwningAnimationTarget& Target() const { return mTarget; }
 | 
						|
 | 
						|
  nsPresContext* GetPresContext() const
 | 
						|
  {
 | 
						|
    return nsContentUtils::GetContextForContent(mTarget.mElement);
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  NonOwningAnimationTarget mTarget;
 | 
						|
};
 | 
						|
 | 
						|
// Return the TransitionPhase or AnimationPhase to use when the animation
 | 
						|
// doesn't have a target effect.
 | 
						|
template <typename PhaseType>
 | 
						|
PhaseType GetAnimationPhaseWithoutEffect(const dom::Animation& aAnimation)
 | 
						|
{
 | 
						|
  MOZ_ASSERT(!aAnimation.GetEffect(),
 | 
						|
             "Should only be called when we do not have an effect");
 | 
						|
 | 
						|
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 | 
						|
// GetTickCount().
 | 
						|
#ifdef GetCurrentTime
 | 
						|
#undef GetCurrentTime
 | 
						|
#endif
 | 
						|
 | 
						|
  dom::Nullable<TimeDuration> currentTime = aAnimation.GetCurrentTime();
 | 
						|
  if (currentTime.IsNull()) {
 | 
						|
    return PhaseType::Idle;
 | 
						|
  }
 | 
						|
 | 
						|
  // If we don't have a target effect, the duration will be zero so the phase is
 | 
						|
  // 'before' if the current time is less than zero.
 | 
						|
  return currentTime.Value() < TimeDuration()
 | 
						|
         ? PhaseType::Before
 | 
						|
         : PhaseType::After;
 | 
						|
};
 | 
						|
 | 
						|
inline TimingParams
 | 
						|
TimingParamsFromCSSParams(float aDuration, float aDelay,
 | 
						|
                          float aIterationCount,
 | 
						|
                          dom::PlaybackDirection aDirection,
 | 
						|
                          dom::FillMode aFillMode)
 | 
						|
{
 | 
						|
  MOZ_ASSERT(aIterationCount >= 0.0 && !IsNaN(aIterationCount),
 | 
						|
             "aIterations should be nonnegative & finite, as ensured by "
 | 
						|
             "CSSParser");
 | 
						|
 | 
						|
  return TimingParams {
 | 
						|
    aDuration,
 | 
						|
    aDelay,
 | 
						|
    aIterationCount,
 | 
						|
    aDirection,
 | 
						|
    aFillMode
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
} // namespace mozilla
 | 
						|
 | 
						|
#endif /* !defined(mozilla_css_AnimationCommon_h) */
 |