forked from mirrors/gecko-dev
		
	MozReview-Commit-ID: BkV6vCc4rmt --HG-- extra : rebase_source : 9a1ef446045adeb7bbab6814c147947e30626b29
		
			
				
	
	
		
			240 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
	
		
			7.4 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_TimingParams_h
 | 
						|
#define mozilla_TimingParams_h
 | 
						|
 | 
						|
#include "nsStringFwd.h"
 | 
						|
#include "mozilla/dom/Nullable.h"
 | 
						|
#include "mozilla/dom/UnionTypes.h" // For OwningUnrestrictedDoubleOrString
 | 
						|
#include "mozilla/ComputedTimingFunction.h"
 | 
						|
#include "mozilla/Maybe.h"
 | 
						|
#include "mozilla/StickyTimeDuration.h"
 | 
						|
#include "mozilla/TimeStamp.h" // for TimeDuration
 | 
						|
 | 
						|
#include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for FillMode
 | 
						|
                                                        // and PlaybackDirection
 | 
						|
 | 
						|
class nsIDocument;
 | 
						|
 | 
						|
namespace mozilla {
 | 
						|
 | 
						|
namespace dom {
 | 
						|
class UnrestrictedDoubleOrKeyframeEffectOptions;
 | 
						|
class UnrestrictedDoubleOrKeyframeAnimationOptions;
 | 
						|
}
 | 
						|
 | 
						|
struct TimingParams
 | 
						|
{
 | 
						|
  TimingParams() = default;
 | 
						|
 | 
						|
  TimingParams(float aDuration, float aDelay,
 | 
						|
               float aIterationCount,
 | 
						|
               dom::PlaybackDirection aDirection,
 | 
						|
               dom::FillMode aFillMode)
 | 
						|
    : mIterations(aIterationCount)
 | 
						|
    , mDirection(aDirection)
 | 
						|
    , mFill(aFillMode)
 | 
						|
  {
 | 
						|
    mDuration.emplace(StickyTimeDuration::FromMilliseconds(aDuration));
 | 
						|
    mDelay = TimeDuration::FromMilliseconds(aDelay);
 | 
						|
    Update();
 | 
						|
  }
 | 
						|
 | 
						|
  TimingParams(const TimeDuration& aDuration,
 | 
						|
               const TimeDuration& aDelay,
 | 
						|
               const TimeDuration& aEndDelay,
 | 
						|
               float aIterations,
 | 
						|
               float aIterationStart,
 | 
						|
               dom::PlaybackDirection aDirection,
 | 
						|
               dom::FillMode aFillMode,
 | 
						|
               Maybe<ComputedTimingFunction>&& aFunction)
 | 
						|
    : mDelay(aDelay)
 | 
						|
    , mEndDelay(aEndDelay)
 | 
						|
    , mIterations(aIterations)
 | 
						|
    , mIterationStart(aIterationStart)
 | 
						|
    , mDirection(aDirection)
 | 
						|
    , mFill(aFillMode)
 | 
						|
    , mFunction(aFunction)
 | 
						|
  {
 | 
						|
    mDuration.emplace(aDuration);
 | 
						|
    Update();
 | 
						|
  }
 | 
						|
 | 
						|
  template <class OptionsType>
 | 
						|
  static TimingParams FromOptionsType(
 | 
						|
    const OptionsType& aOptions,
 | 
						|
    nsIDocument* aDocument,
 | 
						|
    ErrorResult& aRv);
 | 
						|
  static TimingParams FromOptionsUnion(
 | 
						|
    const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
 | 
						|
    nsIDocument* aDocument, ErrorResult& aRv);
 | 
						|
  static TimingParams FromOptionsUnion(
 | 
						|
    const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
 | 
						|
    nsIDocument* aDocument, ErrorResult& aRv);
 | 
						|
 | 
						|
  // Range-checks and validates an UnrestrictedDoubleOrString or
 | 
						|
  // OwningUnrestrictedDoubleOrString object and converts to a
 | 
						|
  // StickyTimeDuration value or Nothing() if aDuration is "auto".
 | 
						|
  // Caller must check aRv.Failed().
 | 
						|
  template <class DoubleOrString>
 | 
						|
  static Maybe<StickyTimeDuration> ParseDuration(DoubleOrString& aDuration,
 | 
						|
                                                 ErrorResult& aRv)
 | 
						|
  {
 | 
						|
    Maybe<StickyTimeDuration> result;
 | 
						|
    if (aDuration.IsUnrestrictedDouble()) {
 | 
						|
      double durationInMs = aDuration.GetAsUnrestrictedDouble();
 | 
						|
      if (durationInMs >= 0) {
 | 
						|
        result.emplace(StickyTimeDuration::FromMilliseconds(durationInMs));
 | 
						|
      } else {
 | 
						|
        aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
 | 
						|
          NS_LITERAL_STRING("duration"));
 | 
						|
      }
 | 
						|
    } else if (!aDuration.GetAsString().EqualsLiteral("auto")) {
 | 
						|
      aRv.ThrowTypeError<dom::MSG_INVALID_DURATION_ERROR>(
 | 
						|
        aDuration.GetAsString());
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  static void ValidateIterationStart(double aIterationStart,
 | 
						|
                                     ErrorResult& aRv)
 | 
						|
  {
 | 
						|
    if (aIterationStart < 0) {
 | 
						|
      aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
 | 
						|
        NS_LITERAL_STRING("iterationStart"));
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  static void ValidateIterations(double aIterations, ErrorResult& aRv)
 | 
						|
  {
 | 
						|
    if (IsNaN(aIterations) || aIterations < 0) {
 | 
						|
      aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
 | 
						|
        NS_LITERAL_STRING("iterations"));
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  static Maybe<ComputedTimingFunction> ParseEasing(const nsAString& aEasing,
 | 
						|
                                                   nsIDocument* aDocument,
 | 
						|
                                                   ErrorResult& aRv);
 | 
						|
 | 
						|
  static StickyTimeDuration CalcActiveDuration(
 | 
						|
    const Maybe<StickyTimeDuration>& aDuration,
 | 
						|
    double aIterations)
 | 
						|
  {
 | 
						|
    // If either the iteration duration or iteration count is zero,
 | 
						|
    // Web Animations says that the active duration is zero. This is to
 | 
						|
    // ensure that the result is defined when the other argument is Infinity.
 | 
						|
    static const StickyTimeDuration zeroDuration;
 | 
						|
    if (!aDuration || aDuration->IsZero() || aIterations == 0.0) {
 | 
						|
      return zeroDuration;
 | 
						|
    }
 | 
						|
 | 
						|
    return aDuration->MultDouble(aIterations);
 | 
						|
  }
 | 
						|
  // Return the duration of the active interval calculated by duration and
 | 
						|
  // iteration count.
 | 
						|
  StickyTimeDuration ActiveDuration() const
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(CalcActiveDuration(mDuration, mIterations) == mActiveDuration,
 | 
						|
               "Cached value of active duration should be up to date");
 | 
						|
    return mActiveDuration;
 | 
						|
  }
 | 
						|
 | 
						|
  StickyTimeDuration EndTime() const
 | 
						|
  {
 | 
						|
    MOZ_ASSERT(mEndTime == std::max(mDelay + ActiveDuration() + mEndDelay,
 | 
						|
                                    StickyTimeDuration()),
 | 
						|
               "Cached value of end time should be up to date");
 | 
						|
    return mEndTime;
 | 
						|
  }
 | 
						|
 | 
						|
  bool operator==(const TimingParams& aOther) const;
 | 
						|
  bool operator!=(const TimingParams& aOther) const
 | 
						|
  {
 | 
						|
    return !(*this == aOther);
 | 
						|
  }
 | 
						|
 | 
						|
  void SetDuration(Maybe<StickyTimeDuration>&& aDuration)
 | 
						|
  {
 | 
						|
    mDuration = Move(aDuration);
 | 
						|
    Update();
 | 
						|
  }
 | 
						|
  const Maybe<StickyTimeDuration>& Duration() const { return mDuration; }
 | 
						|
 | 
						|
  void SetDelay(const TimeDuration& aDelay)
 | 
						|
  {
 | 
						|
    mDelay = aDelay;
 | 
						|
    Update();
 | 
						|
  }
 | 
						|
  const TimeDuration& Delay() const { return mDelay; }
 | 
						|
 | 
						|
  void SetEndDelay(const TimeDuration& aEndDelay)
 | 
						|
  {
 | 
						|
    mEndDelay = aEndDelay;
 | 
						|
    Update();
 | 
						|
  }
 | 
						|
  const TimeDuration& EndDelay() const { return mEndDelay; }
 | 
						|
 | 
						|
  void SetIterations(double aIterations)
 | 
						|
  {
 | 
						|
    mIterations = aIterations;
 | 
						|
    Update();
 | 
						|
  }
 | 
						|
  double Iterations() const { return mIterations; }
 | 
						|
 | 
						|
  void SetIterationStart(double aIterationStart)
 | 
						|
  {
 | 
						|
    mIterationStart = aIterationStart;
 | 
						|
  }
 | 
						|
  double IterationStart() const { return mIterationStart; }
 | 
						|
 | 
						|
  void SetDirection(dom::PlaybackDirection aDirection)
 | 
						|
  {
 | 
						|
    mDirection = aDirection;
 | 
						|
  }
 | 
						|
  dom::PlaybackDirection Direction() const { return mDirection; }
 | 
						|
 | 
						|
  void SetFill(dom::FillMode aFill)
 | 
						|
  {
 | 
						|
    mFill = aFill;
 | 
						|
  }
 | 
						|
  dom::FillMode Fill() const { return mFill; }
 | 
						|
 | 
						|
  void SetTimingFunction(Maybe<ComputedTimingFunction>&& aFunction)
 | 
						|
  {
 | 
						|
    mFunction = Move(aFunction);
 | 
						|
  }
 | 
						|
  const Maybe<ComputedTimingFunction>& TimingFunction() const
 | 
						|
  {
 | 
						|
    return mFunction;
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  void Update()
 | 
						|
  {
 | 
						|
    mActiveDuration = CalcActiveDuration(mDuration, mIterations);
 | 
						|
 | 
						|
    mEndTime = std::max(mDelay + mActiveDuration + mEndDelay,
 | 
						|
                        StickyTimeDuration());
 | 
						|
  }
 | 
						|
 | 
						|
  // mDuration.isNothing() represents the "auto" value
 | 
						|
  Maybe<StickyTimeDuration> mDuration;
 | 
						|
  TimeDuration mDelay;      // Initializes to zero
 | 
						|
  TimeDuration mEndDelay;
 | 
						|
  double mIterations = 1.0; // Can be NaN, negative, +/-Infinity
 | 
						|
  double mIterationStart = 0.0;
 | 
						|
  dom::PlaybackDirection mDirection = dom::PlaybackDirection::Normal;
 | 
						|
  dom::FillMode mFill = dom::FillMode::Auto;
 | 
						|
  Maybe<ComputedTimingFunction> mFunction;
 | 
						|
  StickyTimeDuration mActiveDuration = StickyTimeDuration();
 | 
						|
  StickyTimeDuration mEndTime = StickyTimeDuration();
 | 
						|
};
 | 
						|
 | 
						|
} // namespace mozilla
 | 
						|
 | 
						|
#endif // mozilla_TimingParams_h
 |