Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(279)

Unified Diff: Source/core/animation/AnimatedElement.cpp

Issue 96283002: Web Animations API: Start implementation of Element.animate(). (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/animation/AnimatedElement.cpp
diff --git a/Source/core/animation/AnimatedElement.cpp b/Source/core/animation/AnimatedElement.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..27278a79dfbc5c316c4c0720a8f80e61438675ac
--- /dev/null
+++ b/Source/core/animation/AnimatedElement.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
Steve Block 2013/11/29 07:31:19 NO blank line here
rjwright 2013/12/04 05:05:54 Done.
+#include "core/animation/AnimatedElement.h"
+
+#include "core/animation/AnimatableLength.h"
+#include "core/animation/AnimationEffect.h"
+#include "core/animation/DocumentTimeline.h"
+#include "core/animation/KeyframeAnimationEffect.h"
+#include "core/animation/css/CSSAnimatableValueFactory.h"
+#include "core/animation/css/CSSAnimations.h"
+#include "core/css/resolver/StyleBuilder.h"
+#include "core/css/resolver/StyleResolverState.h"
+#include "core/page/RuntimeCSSEnabled.h"
+#include "core/rendering/style/RenderStyle.h"
+#include "wtf/text/StringBuilder.h"
+
+
+namespace WebCore {
+
+namespace {
+
+static bool isUpper(UChar ch) { return isASCIIUpper(ch); }
Steve Block 2013/11/29 07:31:19 Why do you need this wrapper function?
rjwright 2013/12/04 05:05:54 We don't. Done.
+
+static CSSPropertyID v8PropertyToCSSPropertyID(String propertyName)
Steve Block 2013/11/29 07:31:19 I'm surprised we don't have this logic elsewhere f
apavlov 2013/11/29 09:19:02 FWIW, this logic (and a little bit more :)) is fou
rjwright 2013/12/04 05:05:54 Name change done. The logic exists elsewhere but n
rjwright 2013/12/04 05:05:54 Yes that's where I copied it from. There was no ob
+{
+ StringBuilder builder;
+ size_t position = 0;
+ while (true) {
+ size_t end = propertyName.find(isUpper, position);
+ if (end == kNotFound) {
Steve Block 2013/11/29 07:31:19 Is this simpler ... size_t end; while (end = prop
rjwright 2013/12/04 05:05:54 Done.
+ builder.append(propertyName.substring(position));
+ break;
+ }
+ builder.append(propertyName.substring(position, end) + "-" + toASCIILower(propertyName[end]));
+ position = end + 1;
+ }
+ return cssPropertyID(builder.toString());
+}
+
+} // namespace
+
+void AnimatedElement::animate(Element* element, Vector<Dictionary> dictionaryKeyframesVector)
Steve Block 2013/11/29 07:31:19 s/dictionaryKeyframesVector/keyframeDictionaryVect
rjwright 2013/12/04 05:05:54 Done.
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+
+ KeyframeAnimationEffect::KeyframeVector keyframes;
+ RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
+ for (size_t i = 0; i < dictionaryKeyframesVector.size(); ++i) {
+
+ Vector<String> keyframeProperties;
+ dictionaryKeyframesVector[i].getOwnPropertyNames(keyframeProperties);
+
+ if (!keyframeProperties.size())
Steve Block 2013/11/29 07:31:19 This is incorrect. The spec requires that animatio
rjwright 2013/12/04 05:05:54 Done.
+ continue;
+
+ keyframes.append(Keyframe::create());
Steve Block 2013/11/29 07:31:19 Probably best to build up the keyframe before appe
rjwright 2013/12/04 05:05:54 Done.
+
+ double offset;
+ if (dictionaryKeyframesVector[i].get("offset", offset))
+ keyframes.last()->setOffset(offset);
+ else
+ keyframes.last()->setOffset(std::numeric_limits<double>::quiet_NaN());
Steve Block 2013/11/29 07:31:19 No need for this, it's the default offset for a ke
rjwright 2013/12/04 05:05:54 Done. nullValue()?
+
+ String compositeOperationString;
+ dictionaryKeyframesVector[i].get("compositeOperation", compositeOperationString);
Steve Block 2013/12/02 04:45:45 This should be 'composite'. 'CompositeOperation' i
rjwright 2013/12/04 05:05:54 Done.
+ if (compositeOperationString == String("add"))
+ keyframes.last()->setComposite(AnimationEffect::CompositeAdd);
+ else
+ keyframes.last()->setComposite(AnimationEffect::CompositeReplace);
Steve Block 2013/11/29 07:31:19 Again, keyframes use replace composition by defaul
rjwright 2013/12/04 05:05:54 Done.
+
+ for (size_t j = 0; j < keyframeProperties.size(); ++j) {
+ String property = keyframeProperties[j];
+ String value;
+ dictionaryKeyframesVector[i].get(property, value);
+ CSSPropertyID id = v8PropertyToCSSPropertyID(property);
+
+ if (!id || !CSSAnimations::isAnimatableProperty(id))
Steve Block 2013/11/29 07:31:19 Isn't there a CSSPropertyInvalid we can use here?
rjwright 2013/12/04 05:05:54 If the property from the dictionary isn't a valid
+ continue;
Steve Block 2013/11/29 07:31:19 Again, we shouldn't be skipping invalid keyframes
Steve Block 2013/12/02 01:59:43 I guess we need to decide whether to change the AP
rjwright 2013/12/04 05:05:54 We should discuss this. There's a bunch of differe
+ if (!CSSParser::parseValue(propertySet.get(), id, value, false, element->document()))
+ continue;
Steve Block 2013/11/29 07:31:19 Same as above
rjwright 2013/12/04 05:05:54 I can't change this to anything more meaningful un
+
+ RefPtr<RenderStyle> style = RenderStyle::clone(element->styleForRenderer().get());
+ StyleResolverState state(element->document(), element);
+ state.setStyle(style);
+ StyleBuilder::applyProperty(id, state, propertySet->getPropertyCSSValue(id).get());
+ keyframes.last()->setPropertyValue(id, CSSAnimatableValueFactory::create(id, *style.get()).get());
+ }
+ if (!keyframes.last()->properties().size() && isnan(keyframes.last()->offset()))
Steve Block 2013/11/29 07:31:19 Same comment about getFrames(). Also, use isEmpty(
rjwright 2013/12/04 05:05:54 Done.
+ keyframes.removeLast();
+ }
+
+ RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
+
+ // FIXME: Totally hardcoded Timing for now. Will handle timing parameters later.
+ Timing timing;
+ timing.hasIterationDuration = true;
+ timing.iterationDuration = 1;
+ timing.iterationCount = 1;
Steve Block 2013/11/29 07:31:19 Superfluous. The default iterationCount is 1.
rjwright 2013/12/04 05:05:54 Done.
+
+ RefPtr<Animation> animation = Animation::create(element, effect, timing);
+
+ DocumentTimeline* timeline = element->document().timeline();
Steve Block 2013/11/29 07:31:19 ASSERT(timeline)
rjwright 2013/12/04 05:05:54 Done.
+ // FIXME: If any property appears in only one keyframe (which includes the case where there is
+ // only one keyframe) this crashes.
Steve Block 2013/11/29 07:31:19 This shouldn't be the case. KeyframeAnimationEffec
Steve Block 2013/12/02 04:45:45 I think you're just seeing the fact that add compo
rjwright 2013/12/04 05:05:54 Yep that's it. In that case I'll just pass those c
+ // Handling for this case not yet implemented.
+ // We can check for this here but the check will be pretty clunky. Prefer to add release-assert
+ // where implementation is missing.
+ //
+ // FIXME: If there are more than two keyframes and any of those keyframes doesn't have a specified
Steve Block 2013/11/29 07:31:19 It's not clear which of these you plan to fix befo
rjwright 2013/12/04 05:05:54 Done.
+ // offset, this crashes. If there are exactly two keyframes then missing offsets are ok.
+ // Handling for this case not yet implemented.
Steve Block 2013/11/29 07:31:19 This will be handled by KeyframeAnimationEffect. S
rjwright 2013/12/04 05:05:54 Done.
+ // Can restrict input to 2 keyframes, or check that either all keyframes have offsets
+ // or no keyframes have offsets, or add release assert where implementation is missing.
+ timeline->play(animation.get());
+}
+
+} // namespace WebCore

Powered by Google App Engine
This is Rietveld 408576698