#include "config.h"
#include "core/animation/EffectInput.h"
-#include "bindings/v8/Dictionary.h"
+#include "bindings/core/v8/Dictionary.h"
#include "core/animation/AnimationHelpers.h"
#include "core/animation/KeyframeEffectModel.h"
#include "core/animation/StringKeyframe.h"
#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/CSSToStyleMap.h"
#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "wtf/NonCopyingSort.h"
-namespace WebCore {
+namespace blink {
PassRefPtrWillBeRawPtr<AnimationEffect> EffectInput::convert(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState& exceptionState)
{
StyleSheetContents* styleSheetContents = element->document().elementSheet().contents();
StringKeyframeVector keyframes;
- bool everyFrameHasOffset = true;
- bool looselySortedByOffset = true;
- double lastOffset = -std::numeric_limits<double>::infinity();
+ double lastOffset = 0;
for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
RefPtrWillBeRawPtr<StringKeyframe> keyframe = StringKeyframe::create();
- bool frameHasOffset = false;
- double offset;
- if (keyframeDictionaryVector[i].get("offset", offset)) {
- // Keyframes with offsets outside the range [0.0, 1.0] are ignored.
- if (std::isnan(offset) || offset < 0 || offset > 1)
- continue;
+ ScriptValue scriptValue;
+ bool frameHasOffset = DictionaryHelper::get(keyframeDictionaryVector[i], "offset", scriptValue) && !scriptValue.isNull();
+
+ if (frameHasOffset) {
+ double offset;
+ DictionaryHelper::get(keyframeDictionaryVector[i], "offset", offset);
+
+ // Keyframes with offsets outside the range [0.0, 1.0] are an error.
+ if (std::isnan(offset)) {
+ exceptionState.throwDOMException(InvalidModificationError, "Non numeric offset provided");
+ }
- frameHasOffset = true;
- // The JS value null gets converted to 0 so we need to check whether the original value is null.
- if (offset == 0) {
- ScriptValue scriptValue;
- if (keyframeDictionaryVector[i].get("offset", scriptValue) && scriptValue.isNull())
- frameHasOffset = false;
+ if (offset < 0 || offset > 1) {
+ exceptionState.throwDOMException(InvalidModificationError, "Offsets provided outside the range [0, 1]");
+ return nullptr;
}
- if (frameHasOffset) {
- keyframe->setOffset(offset);
- if (offset < lastOffset)
- looselySortedByOffset = false;
- lastOffset = offset;
+
+ if (offset < lastOffset) {
+ exceptionState.throwDOMException(InvalidModificationError, "Keyframes with specified offsets are not sorted");
+ return nullptr;
}
- }
- everyFrameHasOffset = everyFrameHasOffset && frameHasOffset;
+ lastOffset = offset;
+
+ keyframe->setOffset(offset);
+ }
keyframes.append(keyframe);
String compositeString;
- keyframeDictionaryVector[i].get("composite", compositeString);
+ DictionaryHelper::get(keyframeDictionaryVector[i], "composite", compositeString);
if (compositeString == "add")
keyframe->setComposite(AnimationEffect::CompositeAdd);
String timingFunctionString;
- if (keyframeDictionaryVector[i].get("easing", timingFunctionString)) {
+ if (DictionaryHelper::get(keyframeDictionaryVector[i], "easing", timingFunctionString)) {
if (RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString))
keyframe->setEasing(CSSToStyleMap::mapAnimationTimingFunction(timingFunctionValue.get(), true));
}
if (id == CSSPropertyInvalid)
continue;
String value;
- keyframeDictionaryVector[i].get(property, value);
+ DictionaryHelper::get(keyframeDictionaryVector[i], property, value);
keyframe->setPropertyValue(id, value, styleSheetContents);
}
}
- if (!looselySortedByOffset) {
- if (!everyFrameHasOffset) {
- exceptionState.throwDOMException(InvalidModificationError, "Keyframes are not loosely sorted by offset.");
- return nullptr;
- }
- nonCopyingSort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets);
- }
-
RefPtrWillBeRawPtr<StringKeyframeEffectModel> keyframeEffectModel = StringKeyframeEffectModel::create(keyframes);
if (!keyframeEffectModel->isReplaceOnly()) {
exceptionState.throwDOMException(NotSupportedError, "Partial keyframes are not supported.");
return keyframeEffectModel;
}
-} // namespace WebCore
+} // namespace blink