| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } | 71 } |
| 72 | 72 |
| 73 if (offset < lastOffset) { | 73 if (offset < lastOffset) { |
| 74 exceptionState.throwTypeError("Keyframes with specified offsets are not
sorted"); | 74 exceptionState.throwTypeError("Keyframes with specified offsets are not
sorted"); |
| 75 return false; | 75 return false; |
| 76 } | 76 } |
| 77 | 77 |
| 78 return true; | 78 return true; |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Returns true if the property passed in is a compositable property. | 81 void setKeyframeValue(Element& element, StringKeyframe& keyframe, const String&
property, const String& value) |
| 82 bool setKeyframeValue(Element& element, StringKeyframe& keyframe, const String&
property, const String& value) | |
| 83 { | 82 { |
| 84 StyleSheetContents* styleSheetContents = element.document().elementSheet().c
ontents(); | 83 StyleSheetContents* styleSheetContents = element.document().elementSheet().c
ontents(); |
| 85 CSSPropertyID cssProperty = AnimationInputHelpers::keyframeAttributeToCSSPro
perty(property, element.document()); | 84 CSSPropertyID cssProperty = AnimationInputHelpers::keyframeAttributeToCSSPro
perty(property, element.document()); |
| 86 if (cssProperty != CSSPropertyInvalid) { | 85 if (cssProperty != CSSPropertyInvalid) { |
| 87 keyframe.setCSSPropertyValue(cssProperty, value, &element, styleSheetCon
tents); | 86 keyframe.setCSSPropertyValue(cssProperty, value, &element, styleSheetCon
tents); |
| 88 return CompositorAnimations::isCompositableProperty(cssProperty); | 87 return; |
| 89 } | 88 } |
| 90 cssProperty = AnimationInputHelpers::keyframeAttributeToPresentationAttribut
e(property, element); | 89 cssProperty = AnimationInputHelpers::keyframeAttributeToPresentationAttribut
e(property, element); |
| 91 if (cssProperty != CSSPropertyInvalid) { | 90 if (cssProperty != CSSPropertyInvalid) { |
| 92 keyframe.setPresentationAttributeValue(cssProperty, value, &element, sty
leSheetContents); | 91 keyframe.setPresentationAttributeValue(cssProperty, value, &element, sty
leSheetContents); |
| 93 return false; | 92 return; |
| 94 } | 93 } |
| 95 const QualifiedName* svgAttribute = AnimationInputHelpers::keyframeAttribute
ToSVGAttribute(property, element); | 94 const QualifiedName* svgAttribute = AnimationInputHelpers::keyframeAttribute
ToSVGAttribute(property, element); |
| 96 if (svgAttribute) | 95 if (svgAttribute) |
| 97 keyframe.setSVGAttributeValue(*svgAttribute, value); | 96 keyframe.setSVGAttributeValue(*svgAttribute, value); |
| 98 return false; | |
| 99 } | 97 } |
| 100 | 98 |
| 101 EffectModel* createEffectModelFromKeyframes(Element& element, const StringKeyfra
meVector& keyframes, bool encounteredCompositableProperty, ExceptionState& excep
tionState) | 99 EffectModel* createEffectModelFromKeyframes(Element& element, const StringKeyfra
meVector& keyframes, ExceptionState& exceptionState) |
| 102 { | 100 { |
| 103 // TODO(alancutter): Remove this once composited animations no longer depend
on AnimatableValues. | |
| 104 if (encounteredCompositableProperty && element.inActiveDocument()) | |
| 105 element.document().updateStyleAndLayoutTreeForNode(&element); | |
| 106 | |
| 107 StringKeyframeEffectModel* keyframeEffectModel = StringKeyframeEffectModel::
create(keyframes, LinearTimingFunction::shared()); | 101 StringKeyframeEffectModel* keyframeEffectModel = StringKeyframeEffectModel::
create(keyframes, LinearTimingFunction::shared()); |
| 108 if (!RuntimeEnabledFeatures::cssAdditiveAnimationsEnabled()) { | 102 if (!RuntimeEnabledFeatures::cssAdditiveAnimationsEnabled()) { |
| 109 for (const auto& keyframeGroup : keyframeEffectModel->getPropertySpecifi
cKeyframeGroups()) { | 103 for (const auto& keyframeGroup : keyframeEffectModel->getPropertySpecifi
cKeyframeGroups()) { |
| 110 PropertyHandle property = keyframeGroup.key; | 104 PropertyHandle property = keyframeGroup.key; |
| 111 if (!property.isCSSProperty()) | 105 if (!property.isCSSProperty()) |
| 112 continue; | 106 continue; |
| 113 | 107 |
| 114 for (const auto& keyframe : keyframeGroup.value->keyframes()) { | 108 for (const auto& keyframe : keyframeGroup.value->keyframes()) { |
| 115 if (keyframe->isNeutral()) { | 109 if (keyframe->isNeutral()) { |
| 116 exceptionState.throwDOMException(NotSupportedError, "Partial
keyframes are not supported."); | 110 exceptionState.throwDOMException(NotSupportedError, "Partial
keyframes are not supported."); |
| 117 return nullptr; | 111 return nullptr; |
| 118 } | 112 } |
| 119 if (keyframe->composite() != EffectModel::CompositeReplace) { | 113 if (keyframe->composite() != EffectModel::CompositeReplace) { |
| 120 exceptionState.throwDOMException(NotSupportedError, "Additiv
e animations are not supported."); | 114 exceptionState.throwDOMException(NotSupportedError, "Additiv
e animations are not supported."); |
| 121 return nullptr; | 115 return nullptr; |
| 122 } | 116 } |
| 123 } | 117 } |
| 124 } | 118 } |
| 125 } | 119 } |
| 126 keyframeEffectModel->forceConversionsToAnimatableValues(element, element.com
putedStyle()); | |
| 127 | 120 |
| 128 ASSERT(!exceptionState.hadException()); | 121 ASSERT(!exceptionState.hadException()); |
| 129 return keyframeEffectModel; | 122 return keyframeEffectModel; |
| 130 } | 123 } |
| 131 | 124 |
| 132 bool exhaustDictionaryIterator(DictionaryIterator& iterator, ExecutionContext* e
xecutionContext, ExceptionState& exceptionState, Vector<Dictionary>& result) | 125 bool exhaustDictionaryIterator(DictionaryIterator& iterator, ExecutionContext* e
xecutionContext, ExceptionState& exceptionState, Vector<Dictionary>& result) |
| 133 { | 126 { |
| 134 while (iterator.next(executionContext, exceptionState)) { | 127 while (iterator.next(executionContext, exceptionState)) { |
| 135 Dictionary dictionary; | 128 Dictionary dictionary; |
| 136 if (!iterator.valueAsDictionary(dictionary, exceptionState)) { | 129 if (!iterator.valueAsDictionary(dictionary, exceptionState)) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 166 return nullptr; | 159 return nullptr; |
| 167 } | 160 } |
| 168 | 161 |
| 169 return convertObjectForm(*element, dictionary, exceptionState); | 162 return convertObjectForm(*element, dictionary, exceptionState); |
| 170 } | 163 } |
| 171 | 164 |
| 172 EffectModel* EffectInput::convertArrayForm(Element& element, const Vector<Dictio
nary>& keyframeDictionaries, ExceptionState& exceptionState) | 165 EffectModel* EffectInput::convertArrayForm(Element& element, const Vector<Dictio
nary>& keyframeDictionaries, ExceptionState& exceptionState) |
| 173 { | 166 { |
| 174 StringKeyframeVector keyframes; | 167 StringKeyframeVector keyframes; |
| 175 double lastOffset = 0; | 168 double lastOffset = 0; |
| 176 bool encounteredCompositableProperty = false; | |
| 177 | 169 |
| 178 for (const Dictionary& keyframeDictionary : keyframeDictionaries) { | 170 for (const Dictionary& keyframeDictionary : keyframeDictionaries) { |
| 179 RefPtr<StringKeyframe> keyframe = StringKeyframe::create(); | 171 RefPtr<StringKeyframe> keyframe = StringKeyframe::create(); |
| 180 | 172 |
| 181 ScriptValue scriptValue; | 173 ScriptValue scriptValue; |
| 182 bool frameHasOffset = DictionaryHelper::get(keyframeDictionary, "offset"
, scriptValue) && !scriptValue.isNull(); | 174 bool frameHasOffset = DictionaryHelper::get(keyframeDictionary, "offset"
, scriptValue) && !scriptValue.isNull(); |
| 183 | 175 |
| 184 double offset = 0.0; | 176 double offset = 0.0; |
| 185 if (frameHasOffset) { | 177 if (frameHasOffset) { |
| 186 if (!getAndCheckOffset(keyframeDictionary, offset, lastOffset, excep
tionState)) | 178 if (!getAndCheckOffset(keyframeDictionary, offset, lastOffset, excep
tionState)) |
| (...skipping 27 matching lines...) Expand all Loading... |
| 214 | 206 |
| 215 Vector<String> values; | 207 Vector<String> values; |
| 216 if (DictionaryHelper::get(keyframeDictionary, property, values)) { | 208 if (DictionaryHelper::get(keyframeDictionary, property, values)) { |
| 217 exceptionState.throwTypeError("Lists of values not permitted in
array-form list of keyframes"); | 209 exceptionState.throwTypeError("Lists of values not permitted in
array-form list of keyframes"); |
| 218 return nullptr; | 210 return nullptr; |
| 219 } | 211 } |
| 220 | 212 |
| 221 String value; | 213 String value; |
| 222 DictionaryHelper::get(keyframeDictionary, property, value); | 214 DictionaryHelper::get(keyframeDictionary, property, value); |
| 223 | 215 |
| 224 encounteredCompositableProperty |= setKeyframeValue(element, *keyfra
me.get(), property, value); | 216 setKeyframeValue(element, *keyframe.get(), property, value); |
| 225 } | 217 } |
| 226 keyframes.append(keyframe); | 218 keyframes.append(keyframe); |
| 227 } | 219 } |
| 228 | 220 |
| 229 ASSERT(!exceptionState.hadException()); | 221 ASSERT(!exceptionState.hadException()); |
| 230 | 222 |
| 231 return createEffectModelFromKeyframes(element, keyframes, encounteredComposi
tableProperty, exceptionState); | 223 return createEffectModelFromKeyframes(element, keyframes, exceptionState); |
| 232 } | 224 } |
| 233 | 225 |
| 234 EffectModel* EffectInput::convertObjectForm(Element& element, const Dictionary&
keyframeDictionary, ExceptionState& exceptionState) | 226 EffectModel* EffectInput::convertObjectForm(Element& element, const Dictionary&
keyframeDictionary, ExceptionState& exceptionState) |
| 235 { | 227 { |
| 236 StringKeyframeVector keyframes; | 228 StringKeyframeVector keyframes; |
| 237 bool encounteredCompositableProperty = false; | |
| 238 | 229 |
| 239 String timingFunctionString; | 230 String timingFunctionString; |
| 240 RefPtr<TimingFunction> timingFunction = nullptr; | 231 RefPtr<TimingFunction> timingFunction = nullptr; |
| 241 if (DictionaryHelper::get(keyframeDictionary, "easing", timingFunctionString
)) { | 232 if (DictionaryHelper::get(keyframeDictionary, "easing", timingFunctionString
)) { |
| 242 timingFunction = AnimationInputHelpers::parseTimingFunction(timingFuncti
onString, &element.document(), exceptionState); | 233 timingFunction = AnimationInputHelpers::parseTimingFunction(timingFuncti
onString, &element.document(), exceptionState); |
| 243 if (!timingFunction) | 234 if (!timingFunction) |
| 244 return nullptr; | 235 return nullptr; |
| 245 } | 236 } |
| 246 | 237 |
| 247 ScriptValue scriptValue; | 238 ScriptValue scriptValue; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 else | 272 else |
| 282 keyframe->setOffset(i / (numKeyframes - 1.0)); | 273 keyframe->setOffset(i / (numKeyframes - 1.0)); |
| 283 | 274 |
| 284 if (timingFunction) | 275 if (timingFunction) |
| 285 keyframe->setEasing(timingFunction); | 276 keyframe->setEasing(timingFunction); |
| 286 | 277 |
| 287 if (compositeString == "add") | 278 if (compositeString == "add") |
| 288 keyframe->setComposite(EffectModel::CompositeAdd); | 279 keyframe->setComposite(EffectModel::CompositeAdd); |
| 289 // TODO(alancutter): Support "accumulate" keyframe composition. | 280 // TODO(alancutter): Support "accumulate" keyframe composition. |
| 290 | 281 |
| 291 encounteredCompositableProperty |= setKeyframeValue(element, *keyfra
me.get(), property, values[i]); | 282 setKeyframeValue(element, *keyframe.get(), property, values[i]); |
| 292 keyframes.append(keyframe); | 283 keyframes.append(keyframe); |
| 293 } | 284 } |
| 294 } | 285 } |
| 295 | 286 |
| 296 std::sort(keyframes.begin(), keyframes.end(), compareKeyframes); | 287 std::sort(keyframes.begin(), keyframes.end(), compareKeyframes); |
| 297 | 288 |
| 298 ASSERT(!exceptionState.hadException()); | 289 ASSERT(!exceptionState.hadException()); |
| 299 | 290 |
| 300 return createEffectModelFromKeyframes(element, keyframes, encounteredComposi
tableProperty, exceptionState); | 291 return createEffectModelFromKeyframes(element, keyframes, exceptionState); |
| 301 } | 292 } |
| 302 | 293 |
| 303 } // namespace blink | 294 } // namespace blink |
| OLD | NEW |