6f5c8eaed56b43427b142a3b45f95a2fdae8e83e
[WebKit-https.git] / Source / WebCore / animation / WebAnimation.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebAnimation.h"
28
29 #include "AnimationEffect.h"
30 #include "AnimationTimeline.h"
31 #include "Document.h"
32 #include <wtf/text/WTFString.h>
33
34 namespace WebCore {
35
36 Ref<WebAnimation> WebAnimation::create(Document& document, AnimationEffect* effect, AnimationTimeline* timeline)
37 {
38     auto result = adoptRef(*new WebAnimation());
39
40     result->setEffect(effect);
41     
42     // FIXME: the spec mandates distinguishing between an omitted timeline parameter
43     // and an explicit null or undefined value (webkit.org/b/179065).
44     result->setTimeline(timeline ? timeline : &document.timeline());
45     
46     return result;
47 }
48
49 WebAnimation::WebAnimation()
50 {
51 }
52
53 WebAnimation::~WebAnimation()
54 {
55     if (m_timeline)
56         m_timeline->removeAnimation(*this);
57 }
58
59 void WebAnimation::setEffect(RefPtr<AnimationEffect>&& effect)
60 {
61     if (effect == m_effect)
62         return;
63
64     m_effect = WTFMove(effect);
65 }
66
67 void WebAnimation::setTimeline(RefPtr<AnimationTimeline>&& timeline)
68 {
69     if (timeline == m_timeline)
70         return;
71
72     // FIXME: If the animation start time of animation is resolved, make animation’s
73     // hold time unresolved (webkit.org/b/178932).
74
75     if (m_timeline)
76         m_timeline->removeAnimation(*this);
77
78     if (timeline)
79         timeline->addAnimation(*this);
80
81     m_timeline = WTFMove(timeline);
82 }
83     
84 std::optional<double> WebAnimation::bindingsStartTime() const
85 {
86     if (m_startTime)
87         return m_startTime->value();
88     return std::nullopt;
89 }
90
91 void WebAnimation::setBindingsStartTime(std::optional<double> startTime)
92 {
93     if (startTime == std::nullopt)
94         setStartTime(std::nullopt);
95     else
96         setStartTime(Seconds(startTime.value()));
97 }
98
99 std::optional<Seconds> WebAnimation::startTime() const
100 {
101     return m_startTime;
102 }
103
104 void WebAnimation::setStartTime(std::optional<Seconds> startTime)
105 {
106     if (startTime == m_startTime)
107         return;
108
109     m_startTime = startTime;
110 }
111
112 std::optional<double> WebAnimation::bindingsCurrentTime() const
113 {
114     auto time = currentTime();
115     if (!time)
116         return std::nullopt;
117     return time->value();
118 }
119
120 ExceptionOr<void> WebAnimation::setBindingsCurrentTime(std::optional<double> currentTime)
121 {
122     if (!currentTime)
123         return Exception { TypeError };
124     setCurrentTime(Seconds(currentTime.value()));
125     return { };
126 }
127
128 std::optional<Seconds> WebAnimation::currentTime() const
129 {
130     // FIXME: return the hold time when we support pausing (webkit.org/b/178932).
131
132     if (!m_timeline || !m_startTime)
133         return std::nullopt;
134
135     auto timelineTime = m_timeline->currentTime();
136     if (!timelineTime)
137         return std::nullopt;
138
139     return (timelineTime.value() - m_startTime.value()) * m_playbackRate;
140 }
141
142 void WebAnimation::setCurrentTime(std::optional<Seconds> seekTime)
143 {
144     // FIXME: account for hold time when we support it (webkit.org/b/178932),
145     // including situations where playbackRate is 0.
146
147     if (!m_timeline) {
148         setStartTime(std::nullopt);
149         return;
150     }
151
152     auto timelineTime = m_timeline->currentTime();
153     if (!timelineTime) {
154         setStartTime(std::nullopt);
155         return;
156     }
157
158     setStartTime(timelineTime.value() - (seekTime.value() / m_playbackRate));
159 }
160
161 void WebAnimation::setPlaybackRate(double newPlaybackRate)
162 {
163     if (m_playbackRate == newPlaybackRate)
164         return;
165
166     // 3.5.17.1. Updating the playback rate of an animation
167     // Changes to the playback rate trigger a compensatory seek so that that the animation's current time
168     // is unaffected by the change to the playback rate.
169     auto previousTime = currentTime();
170     m_playbackRate = newPlaybackRate;
171     if (previousTime)
172         setCurrentTime(previousTime);
173 }
174
175 String WebAnimation::description()
176 {
177     return "Animation";
178 }
179
180 } // namespace WebCore