Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/animation/TimingParams.cpp
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
#include "mozilla/TimingParams.h"
8
9
#include "mozilla/AnimationUtils.h"
10
#include "mozilla/dom/AnimatableBinding.h"
11
#include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
12
#include "mozilla/dom/KeyframeEffectBinding.h"
13
#include "mozilla/ServoCSSParser.h"
14
#include "nsIDocument.h"
15
16
namespace mozilla {
17
18
template <class OptionsType>
19
static const dom::EffectTiming&
20
GetTimingProperties(const OptionsType& aOptions);
21
22
template <>
23
/* static */ const dom::EffectTiming&
24
GetTimingProperties(
25
  const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions)
26
0
{
27
0
  MOZ_ASSERT(aOptions.IsKeyframeEffectOptions());
28
0
  return aOptions.GetAsKeyframeEffectOptions();
29
0
}
30
31
template <>
32
/* static */ const dom::EffectTiming&
33
GetTimingProperties(
34
  const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions)
35
0
{
36
0
  MOZ_ASSERT(aOptions.IsKeyframeAnimationOptions());
37
0
  return aOptions.GetAsKeyframeAnimationOptions();
38
0
}
39
40
template <class OptionsType>
41
/* static */ TimingParams
42
TimingParams::FromOptionsType(const OptionsType& aOptions,
43
                              nsIDocument* aDocument,
44
                              ErrorResult& aRv)
45
0
{
46
0
  TimingParams result;
47
0
48
0
  if (aOptions.IsUnrestrictedDouble()) {
49
0
    double durationInMs = aOptions.GetAsUnrestrictedDouble();
50
0
    if (durationInMs >= 0) {
51
0
      result.mDuration.emplace(
52
0
        StickyTimeDuration::FromMilliseconds(durationInMs));
53
0
    } else {
54
0
      aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
55
0
      return result;
56
0
    }
57
0
    result.Update();
58
0
  } else {
59
0
    const dom::EffectTiming& timing = GetTimingProperties(aOptions);
60
0
    result = FromEffectTiming(timing, aDocument, aRv);
61
0
  }
62
0
63
0
  return result;
64
0
}
Unexecuted instantiation: mozilla::TimingParams mozilla::TimingParams::FromOptionsType<mozilla::dom::UnrestrictedDoubleOrKeyframeEffectOptions>(mozilla::dom::UnrestrictedDoubleOrKeyframeEffectOptions const&, nsIDocument*, mozilla::ErrorResult&)
Unexecuted instantiation: mozilla::TimingParams mozilla::TimingParams::FromOptionsType<mozilla::dom::UnrestrictedDoubleOrKeyframeAnimationOptions>(mozilla::dom::UnrestrictedDoubleOrKeyframeAnimationOptions const&, nsIDocument*, mozilla::ErrorResult&)
65
66
/* static */ TimingParams
67
TimingParams::FromOptionsUnion(
68
  const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
69
  nsIDocument* aDocument,
70
  ErrorResult& aRv)
71
0
{
72
0
  return FromOptionsType(aOptions, aDocument, aRv);
73
0
}
74
75
/* static */ TimingParams
76
TimingParams::FromOptionsUnion(
77
  const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
78
  nsIDocument* aDocument,
79
  ErrorResult& aRv)
80
0
{
81
0
  return FromOptionsType(aOptions, aDocument, aRv);
82
0
}
83
84
/* static */ TimingParams
85
TimingParams::FromEffectTiming(const dom::EffectTiming& aEffectTiming,
86
                               nsIDocument* aDocument,
87
                               ErrorResult& aRv)
88
0
{
89
0
  TimingParams result;
90
0
91
0
  Maybe<StickyTimeDuration> duration =
92
0
    TimingParams::ParseDuration(aEffectTiming.mDuration, aRv);
93
0
  if (aRv.Failed()) {
94
0
    return result;
95
0
  }
96
0
  TimingParams::ValidateIterationStart(aEffectTiming.mIterationStart, aRv);
97
0
  if (aRv.Failed()) {
98
0
    return result;
99
0
  }
100
0
  TimingParams::ValidateIterations(aEffectTiming.mIterations, aRv);
101
0
  if (aRv.Failed()) {
102
0
    return result;
103
0
  }
104
0
  Maybe<ComputedTimingFunction> easing =
105
0
    TimingParams::ParseEasing(aEffectTiming.mEasing, aDocument, aRv);
106
0
  if (aRv.Failed()) {
107
0
    return result;
108
0
  }
109
0
110
0
  result.mDuration = duration;
111
0
  result.mDelay = TimeDuration::FromMilliseconds(aEffectTiming.mDelay);
112
0
  result.mEndDelay = TimeDuration::FromMilliseconds(aEffectTiming.mEndDelay);
113
0
  result.mIterations = aEffectTiming.mIterations;
114
0
  result.mIterationStart = aEffectTiming.mIterationStart;
115
0
  result.mDirection = aEffectTiming.mDirection;
116
0
  result.mFill = aEffectTiming.mFill;
117
0
  result.mFunction = easing;
118
0
119
0
  result.Update();
120
0
121
0
  return result;
122
0
}
123
124
/* static */ TimingParams
125
TimingParams::MergeOptionalEffectTiming(
126
  const TimingParams& aSource,
127
  const dom::OptionalEffectTiming& aEffectTiming,
128
  nsIDocument* aDocument,
129
  ErrorResult& aRv)
130
0
{
131
0
  MOZ_ASSERT(!aRv.Failed(), "Initially return value should be ok");
132
0
133
0
  TimingParams result = aSource;
134
0
135
0
  // Check for errors first
136
0
137
0
  Maybe<StickyTimeDuration> duration;
138
0
  if (aEffectTiming.mDuration.WasPassed()) {
139
0
    duration =
140
0
      TimingParams::ParseDuration(aEffectTiming.mDuration.Value(), aRv);
141
0
    if (aRv.Failed()) {
142
0
      return result;
143
0
    }
144
0
  }
145
0
146
0
  if (aEffectTiming.mIterationStart.WasPassed()) {
147
0
    TimingParams::ValidateIterationStart(aEffectTiming.mIterationStart.Value(),
148
0
                                         aRv);
149
0
    if (aRv.Failed()) {
150
0
      return result;
151
0
    }
152
0
  }
153
0
154
0
  if (aEffectTiming.mIterations.WasPassed()) {
155
0
    TimingParams::ValidateIterations(aEffectTiming.mIterations.Value(), aRv);
156
0
    if (aRv.Failed()) {
157
0
      return result;
158
0
    }
159
0
  }
160
0
161
0
  Maybe<ComputedTimingFunction> easing;
162
0
  if (aEffectTiming.mEasing.WasPassed()) {
163
0
    easing =
164
0
      TimingParams::ParseEasing(aEffectTiming.mEasing.Value(), aDocument, aRv);
165
0
    if (aRv.Failed()) {
166
0
      return result;
167
0
    }
168
0
  }
169
0
170
0
  // Assign values
171
0
172
0
  if (aEffectTiming.mDuration.WasPassed()) {
173
0
    result.mDuration = duration;
174
0
  }
175
0
  if (aEffectTiming.mDelay.WasPassed()) {
176
0
    result.mDelay =
177
0
      TimeDuration::FromMilliseconds(aEffectTiming.mDelay.Value());
178
0
  }
179
0
  if (aEffectTiming.mEndDelay.WasPassed()) {
180
0
    result.mEndDelay =
181
0
      TimeDuration::FromMilliseconds(aEffectTiming.mEndDelay.Value());
182
0
  }
183
0
  if (aEffectTiming.mIterations.WasPassed()) {
184
0
    result.mIterations = aEffectTiming.mIterations.Value();
185
0
  }
186
0
  if (aEffectTiming.mIterationStart.WasPassed()) {
187
0
    result.mIterationStart = aEffectTiming.mIterationStart.Value();
188
0
  }
189
0
  if (aEffectTiming.mDirection.WasPassed()) {
190
0
    result.mDirection = aEffectTiming.mDirection.Value();
191
0
  }
192
0
  if (aEffectTiming.mFill.WasPassed()) {
193
0
    result.mFill = aEffectTiming.mFill.Value();
194
0
  }
195
0
  if (aEffectTiming.mEasing.WasPassed()) {
196
0
    result.mFunction = easing;
197
0
  }
198
0
199
0
  result.Update();
200
0
201
0
  return result;
202
0
}
203
204
/* static */ Maybe<ComputedTimingFunction>
205
TimingParams::ParseEasing(const nsAString& aEasing,
206
                          nsIDocument* aDocument,
207
                          ErrorResult& aRv)
208
0
{
209
0
  MOZ_ASSERT(aDocument);
210
0
211
0
  nsTimingFunction timingFunction;
212
0
  RefPtr<URLExtraData> url = ServoCSSParser::GetURLExtraData(aDocument);
213
0
  if (!ServoCSSParser::ParseEasing(aEasing, url, timingFunction)) {
214
0
    aRv.ThrowTypeError<dom::MSG_INVALID_EASING_ERROR>(aEasing);
215
0
    return Nothing();
216
0
  }
217
0
218
0
  if (timingFunction.mType == nsTimingFunction::Type::Linear) {
219
0
    return Nothing();
220
0
  }
221
0
222
0
  return Some(ComputedTimingFunction(timingFunction));
223
0
}
224
225
bool
226
TimingParams::operator==(const TimingParams& aOther) const
227
0
{
228
0
  // We don't compare mActiveDuration and mEndTime because they are calculated
229
0
  // from other timing parameters.
230
0
  return mDuration == aOther.mDuration &&
231
0
         mDelay == aOther.mDelay &&
232
0
         mEndDelay == aOther.mEndDelay &&
233
0
         mIterations == aOther.mIterations &&
234
0
         mIterationStart == aOther.mIterationStart &&
235
0
         mDirection == aOther.mDirection &&
236
0
         mFill == aOther.mFill &&
237
0
         mFunction == aOther.mFunction;
238
0
}
239
240
} // namespace mozilla