1/*
2 * Copyright (C) 2018 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 "CSSAnimation.h"
28
29#include "Animation.h"
30#include "Element.h"
31#include "RenderStyle.h"
32#include <wtf/IsoMallocInlines.h>
33
34namespace WebCore {
35
36WTF_MAKE_ISO_ALLOCATED_IMPL(CSSAnimation);
37
38Ref<CSSAnimation> CSSAnimation::create(Element& owningElement, const Animation& backingAnimation, const RenderStyle* oldStyle, const RenderStyle& newStyle)
39{
40 auto result = adoptRef(*new CSSAnimation(owningElement, backingAnimation, newStyle));
41 result->initialize(oldStyle, newStyle);
42 return result;
43}
44
45CSSAnimation::CSSAnimation(Element& element, const Animation& backingAnimation, const RenderStyle& unanimatedStyle)
46 : DeclarativeAnimation(element, backingAnimation)
47 , m_animationName(backingAnimation.name())
48 , m_unanimatedStyle(RenderStyle::clonePtr(unanimatedStyle))
49{
50}
51
52void CSSAnimation::syncPropertiesWithBackingAnimation()
53{
54 DeclarativeAnimation::syncPropertiesWithBackingAnimation();
55
56 if (!effect())
57 return;
58
59 suspendEffectInvalidation();
60
61 auto& animation = backingAnimation();
62 auto* animationEffect = effect();
63
64 switch (animation.fillMode()) {
65 case AnimationFillMode::None:
66 animationEffect->setFill(FillMode::None);
67 break;
68 case AnimationFillMode::Backwards:
69 animationEffect->setFill(FillMode::Backwards);
70 break;
71 case AnimationFillMode::Forwards:
72 animationEffect->setFill(FillMode::Forwards);
73 break;
74 case AnimationFillMode::Both:
75 animationEffect->setFill(FillMode::Both);
76 break;
77 }
78
79 switch (animation.direction()) {
80 case Animation::AnimationDirectionNormal:
81 animationEffect->setDirection(PlaybackDirection::Normal);
82 break;
83 case Animation::AnimationDirectionAlternate:
84 animationEffect->setDirection(PlaybackDirection::Alternate);
85 break;
86 case Animation::AnimationDirectionReverse:
87 animationEffect->setDirection(PlaybackDirection::Reverse);
88 break;
89 case Animation::AnimationDirectionAlternateReverse:
90 animationEffect->setDirection(PlaybackDirection::AlternateReverse);
91 break;
92 }
93
94 auto iterationCount = animation.iterationCount();
95 animationEffect->setIterations(iterationCount == Animation::IterationCountInfinite ? std::numeric_limits<double>::infinity() : iterationCount);
96
97 animationEffect->setDelay(Seconds(animation.delay()));
98 animationEffect->setIterationDuration(Seconds(animation.duration()));
99
100 // Synchronize the play state
101 if (animation.playState() == AnimationPlayState::Playing && playState() == WebAnimation::PlayState::Paused) {
102 if (!m_stickyPaused)
103 play();
104 } else if (animation.playState() == AnimationPlayState::Paused && playState() == WebAnimation::PlayState::Running)
105 pause();
106
107 unsuspendEffectInvalidation();
108}
109
110ExceptionOr<void> CSSAnimation::bindingsPlay()
111{
112 m_stickyPaused = false;
113 return DeclarativeAnimation::bindingsPlay();
114}
115
116ExceptionOr<void> CSSAnimation::bindingsPause()
117{
118 m_stickyPaused = true;
119 return DeclarativeAnimation::bindingsPause();
120}
121
122} // namespace WebCore
123