1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "core/animation/TimingInput.h" 7 8 #include "bindings/v8/Dictionary.h" 9 #include "core/css/parser/BisonCSSParser.h" 10 #include "core/css/resolver/CSSToStyleMap.h" 11 12 namespace WebCore { 13 14 void TimingInput::setStartDelay(Timing& timing, double startDelay) 15 { 16 if (std::isfinite(startDelay)) 17 timing.startDelay = startDelay / 1000; 18 else 19 timing.startDelay = Timing::defaults().startDelay; 20 } 21 22 void TimingInput::setEndDelay(Timing& timing, double endDelay) 23 { 24 if (std::isfinite(endDelay)) 25 timing.endDelay = endDelay / 1000; 26 else 27 timing.endDelay = Timing::defaults().endDelay; 28 } 29 30 void TimingInput::setFillMode(Timing& timing, const String& fillMode) 31 { 32 if (fillMode == "none") { 33 timing.fillMode = Timing::FillModeNone; 34 } else if (fillMode == "backwards") { 35 timing.fillMode = Timing::FillModeBackwards; 36 } else if (fillMode == "both") { 37 timing.fillMode = Timing::FillModeBoth; 38 } else if (fillMode == "forwards") { 39 timing.fillMode = Timing::FillModeForwards; 40 } else { 41 timing.fillMode = Timing::defaults().fillMode; 42 } 43 } 44 45 void TimingInput::setIterationStart(Timing& timing, double iterationStart) 46 { 47 if (std::isfinite(iterationStart)) 48 timing.iterationStart = std::max<double>(iterationStart, 0); 49 else 50 timing.iterationStart = Timing::defaults().iterationStart; 51 } 52 53 void TimingInput::setIterationCount(Timing& timing, double iterationCount) 54 { 55 if (!std::isnan(iterationCount)) 56 timing.iterationCount = std::max<double>(iterationCount, 0); 57 else 58 timing.iterationCount = Timing::defaults().iterationCount; 59 } 60 61 void TimingInput::setIterationDuration(Timing& timing, double iterationDuration) 62 { 63 if (!std::isnan(iterationDuration) && iterationDuration >= 0) 64 timing.iterationDuration = iterationDuration / 1000; 65 else 66 timing.iterationDuration = Timing::defaults().iterationDuration; 67 } 68 69 void TimingInput::setPlaybackRate(Timing& timing, double playbackRate) 70 { 71 if (std::isfinite(playbackRate)) 72 timing.playbackRate = playbackRate; 73 else 74 timing.playbackRate = Timing::defaults().playbackRate; 75 } 76 77 void TimingInput::setPlaybackDirection(Timing& timing, const String& direction) 78 { 79 if (direction == "reverse") { 80 timing.direction = Timing::PlaybackDirectionReverse; 81 } else if (direction == "alternate") { 82 timing.direction = Timing::PlaybackDirectionAlternate; 83 } else if (direction == "alternate-reverse") { 84 timing.direction = Timing::PlaybackDirectionAlternateReverse; 85 } else { 86 timing.direction = Timing::defaults().direction; 87 } 88 } 89 90 void TimingInput::setTimingFunction(Timing& timing, const String& timingFunctionString) 91 { 92 if (RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString)) 93 timing.timingFunction = CSSToStyleMap::mapAnimationTimingFunction(timingFunctionValue.get(), true); 94 else 95 timing.timingFunction = Timing::defaults().timingFunction; 96 } 97 98 Timing TimingInput::convert(const Dictionary& timingInputDictionary) 99 { 100 Timing result; 101 102 // FIXME: This method needs to be refactored to handle invalid 103 // null, NaN, Infinity values better. 104 // See: http://www.w3.org/TR/WebIDL/#es-double 105 double startDelay = Timing::defaults().startDelay; 106 timingInputDictionary.get("delay", startDelay); 107 setStartDelay(result, startDelay); 108 109 double endDelay = Timing::defaults().endDelay; 110 timingInputDictionary.get("endDelay", endDelay); 111 setEndDelay(result, endDelay); 112 113 String fillMode; 114 timingInputDictionary.get("fill", fillMode); 115 setFillMode(result, fillMode); 116 117 double iterationStart = Timing::defaults().iterationStart; 118 timingInputDictionary.get("iterationStart", iterationStart); 119 setIterationStart(result, iterationStart); 120 121 double iterationCount = Timing::defaults().iterationCount; 122 timingInputDictionary.get("iterations", iterationCount); 123 setIterationCount(result, iterationCount); 124 125 double iterationDuration = 0; 126 if (timingInputDictionary.get("duration", iterationDuration)) { 127 setIterationDuration(result, iterationDuration); 128 } 129 130 double playbackRate = Timing::defaults().playbackRate; 131 timingInputDictionary.get("playbackRate", playbackRate); 132 setPlaybackRate(result, playbackRate); 133 134 String direction; 135 timingInputDictionary.get("direction", direction); 136 setPlaybackDirection(result, direction); 137 138 String timingFunctionString; 139 timingInputDictionary.get("easing", timingFunctionString); 140 setTimingFunction(result, timingFunctionString); 141 142 result.assertValid(); 143 144 return result; 145 } 146 147 Timing TimingInput::convert(double duration) 148 { 149 Timing result; 150 setIterationDuration(result, duration); 151 return result; 152 } 153 154 } // namespace WebCore 155