Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/TimingParams.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_TimingParams_h
8
#define mozilla_TimingParams_h
9
10
#include "nsStringFwd.h"
11
#include "mozilla/dom/Nullable.h"
12
#include "mozilla/dom/UnionTypes.h" // For OwningUnrestrictedDoubleOrString
13
#include "mozilla/ComputedTimingFunction.h"
14
#include "mozilla/Maybe.h"
15
#include "mozilla/StickyTimeDuration.h"
16
#include "mozilla/TimeStamp.h" // for TimeDuration
17
18
#include "mozilla/dom/AnimationEffectBinding.h" // for FillMode
19
                                                // and PlaybackDirection
20
21
class nsIDocument;
22
23
namespace mozilla {
24
25
namespace dom {
26
class UnrestrictedDoubleOrKeyframeEffectOptions;
27
class UnrestrictedDoubleOrKeyframeAnimationOptions;
28
}
29
30
struct TimingParams
31
{
32
0
  TimingParams() = default;
33
34
  TimingParams(float aDuration, float aDelay,
35
               float aIterationCount,
36
               dom::PlaybackDirection aDirection,
37
               dom::FillMode aFillMode)
38
    : mIterations(aIterationCount)
39
    , mDirection(aDirection)
40
    , mFill(aFillMode)
41
0
  {
42
0
    mDuration.emplace(StickyTimeDuration::FromMilliseconds(aDuration));
43
0
    mDelay = TimeDuration::FromMilliseconds(aDelay);
44
0
    Update();
45
0
  }
46
47
  TimingParams(const TimeDuration& aDuration,
48
               const TimeDuration& aDelay,
49
               const TimeDuration& aEndDelay,
50
               float aIterations,
51
               float aIterationStart,
52
               dom::PlaybackDirection aDirection,
53
               dom::FillMode aFillMode,
54
               Maybe<ComputedTimingFunction>&& aFunction)
55
    : mDelay(aDelay)
56
    , mEndDelay(aEndDelay)
57
    , mIterations(aIterations)
58
    , mIterationStart(aIterationStart)
59
    , mDirection(aDirection)
60
    , mFill(aFillMode)
61
    , mFunction(aFunction)
62
0
  {
63
0
    mDuration.emplace(aDuration);
64
0
    Update();
65
0
  }
66
67
  template <class OptionsType>
68
  static TimingParams FromOptionsType(
69
    const OptionsType& aOptions,
70
    nsIDocument* aDocument,
71
    ErrorResult& aRv);
72
  static TimingParams FromOptionsUnion(
73
    const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
74
    nsIDocument* aDocument, ErrorResult& aRv);
75
  static TimingParams FromOptionsUnion(
76
    const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
77
    nsIDocument* aDocument, ErrorResult& aRv);
78
  static TimingParams FromEffectTiming(
79
    const dom::EffectTiming& aEffectTiming,
80
    nsIDocument* aDocument,
81
    ErrorResult& aRv);
82
  // Returns a copy of |aSource| where each timing property in |aSource| that
83
  // is also specified in |aEffectTiming| is replaced with the value from
84
  // |aEffectTiming|.
85
  //
86
  // If any of the values in |aEffectTiming| are invalid, |aRv.Failed()| will be
87
  // true and an unmodified copy of |aSource| will be returned.
88
  static TimingParams MergeOptionalEffectTiming(
89
    const TimingParams& aSource,
90
    const dom::OptionalEffectTiming& aEffectTiming,
91
    nsIDocument* aDocument,
92
    ErrorResult& aRv);
93
94
  // Range-checks and validates an UnrestrictedDoubleOrString or
95
  // OwningUnrestrictedDoubleOrString object and converts to a
96
  // StickyTimeDuration value or Nothing() if aDuration is "auto".
97
  // Caller must check aRv.Failed().
98
  template <class DoubleOrString>
99
  static Maybe<StickyTimeDuration> ParseDuration(DoubleOrString& aDuration,
100
                                                 ErrorResult& aRv)
101
0
  {
102
0
    Maybe<StickyTimeDuration> result;
103
0
    if (aDuration.IsUnrestrictedDouble()) {
104
0
      double durationInMs = aDuration.GetAsUnrestrictedDouble();
105
0
      if (durationInMs >= 0) {
106
0
        result.emplace(StickyTimeDuration::FromMilliseconds(durationInMs));
107
0
      } else {
108
0
        aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
109
0
          NS_LITERAL_STRING("duration"));
110
0
      }
111
0
    } else if (!aDuration.GetAsString().EqualsLiteral("auto")) {
112
0
      aRv.ThrowTypeError<dom::MSG_INVALID_DURATION_ERROR>(
113
0
        aDuration.GetAsString());
114
0
    }
115
0
    return result;
116
0
  }
117
118
  static void ValidateIterationStart(double aIterationStart,
119
                                     ErrorResult& aRv)
120
0
  {
121
0
    if (aIterationStart < 0) {
122
0
      aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
123
0
        NS_LITERAL_STRING("iterationStart"));
124
0
    }
125
0
  }
126
127
  static void ValidateIterations(double aIterations, ErrorResult& aRv)
128
0
  {
129
0
    if (IsNaN(aIterations) || aIterations < 0) {
130
0
      aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
131
0
        NS_LITERAL_STRING("iterations"));
132
0
    }
133
0
  }
134
135
  static Maybe<ComputedTimingFunction> ParseEasing(const nsAString& aEasing,
136
                                                   nsIDocument* aDocument,
137
                                                   ErrorResult& aRv);
138
139
  static StickyTimeDuration CalcActiveDuration(
140
    const Maybe<StickyTimeDuration>& aDuration,
141
    double aIterations)
142
0
  {
143
0
    // If either the iteration duration or iteration count is zero,
144
0
    // Web Animations says that the active duration is zero. This is to
145
0
    // ensure that the result is defined when the other argument is Infinity.
146
0
    static const StickyTimeDuration zeroDuration;
147
0
    if (!aDuration || aDuration->IsZero() || aIterations == 0.0) {
148
0
      return zeroDuration;
149
0
    }
150
0
151
0
    return aDuration->MultDouble(aIterations);
152
0
  }
153
  // Return the duration of the active interval calculated by duration and
154
  // iteration count.
155
  StickyTimeDuration ActiveDuration() const
156
0
  {
157
0
    MOZ_ASSERT(CalcActiveDuration(mDuration, mIterations) == mActiveDuration,
158
0
               "Cached value of active duration should be up to date");
159
0
    return mActiveDuration;
160
0
  }
161
162
  StickyTimeDuration EndTime() const
163
0
  {
164
0
    MOZ_ASSERT(mEndTime == std::max(mDelay + ActiveDuration() + mEndDelay,
165
0
                                    StickyTimeDuration()),
166
0
               "Cached value of end time should be up to date");
167
0
    return mEndTime;
168
0
  }
169
170
  bool operator==(const TimingParams& aOther) const;
171
  bool operator!=(const TimingParams& aOther) const
172
0
  {
173
0
    return !(*this == aOther);
174
0
  }
175
176
  void SetDuration(Maybe<StickyTimeDuration>&& aDuration)
177
0
  {
178
0
    mDuration = std::move(aDuration);
179
0
    Update();
180
0
  }
181
0
  const Maybe<StickyTimeDuration>& Duration() const { return mDuration; }
182
183
  void SetDelay(const TimeDuration& aDelay)
184
0
  {
185
0
    mDelay = aDelay;
186
0
    Update();
187
0
  }
188
0
  const TimeDuration& Delay() const { return mDelay; }
189
190
  void SetEndDelay(const TimeDuration& aEndDelay)
191
0
  {
192
0
    mEndDelay = aEndDelay;
193
0
    Update();
194
0
  }
195
0
  const TimeDuration& EndDelay() const { return mEndDelay; }
196
197
  void SetIterations(double aIterations)
198
0
  {
199
0
    mIterations = aIterations;
200
0
    Update();
201
0
  }
202
0
  double Iterations() const { return mIterations; }
203
204
  void SetIterationStart(double aIterationStart)
205
0
  {
206
0
    mIterationStart = aIterationStart;
207
0
  }
208
0
  double IterationStart() const { return mIterationStart; }
209
210
  void SetDirection(dom::PlaybackDirection aDirection)
211
0
  {
212
0
    mDirection = aDirection;
213
0
  }
214
0
  dom::PlaybackDirection Direction() const { return mDirection; }
215
216
  void SetFill(dom::FillMode aFill)
217
0
  {
218
0
    mFill = aFill;
219
0
  }
220
0
  dom::FillMode Fill() const { return mFill; }
221
222
  void SetTimingFunction(Maybe<ComputedTimingFunction>&& aFunction)
223
0
  {
224
0
    mFunction = std::move(aFunction);
225
0
  }
226
  const Maybe<ComputedTimingFunction>& TimingFunction() const
227
0
  {
228
0
    return mFunction;
229
0
  }
230
231
private:
232
  void Update()
233
0
  {
234
0
    mActiveDuration = CalcActiveDuration(mDuration, mIterations);
235
0
236
0
    mEndTime = std::max(mDelay + mActiveDuration + mEndDelay,
237
0
                        StickyTimeDuration());
238
0
  }
239
240
  // mDuration.isNothing() represents the "auto" value
241
  Maybe<StickyTimeDuration> mDuration;
242
  TimeDuration mDelay;      // Initializes to zero
243
  TimeDuration mEndDelay;
244
  double mIterations = 1.0; // Can be NaN, negative, +/-Infinity
245
  double mIterationStart = 0.0;
246
  dom::PlaybackDirection mDirection = dom::PlaybackDirection::Normal;
247
  dom::FillMode mFill = dom::FillMode::Auto;
248
  Maybe<ComputedTimingFunction> mFunction;
249
  StickyTimeDuration mActiveDuration = StickyTimeDuration();
250
  StickyTimeDuration mEndTime = StickyTimeDuration();
251
};
252
253
} // namespace mozilla
254
255
#endif // mozilla_TimingParams_h