summaryrefslogtreecommitdiff
path: root/Source/WebCore/page/animation/CompositeAnimation.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/page/animation/CompositeAnimation.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/page/animation/CompositeAnimation.cpp')
-rw-r--r--Source/WebCore/page/animation/CompositeAnimation.cpp444
1 files changed, 232 insertions, 212 deletions
diff --git a/Source/WebCore/page/animation/CompositeAnimation.cpp b/Source/WebCore/page/animation/CompositeAnimation.cpp
index e18779ea7..f89f1e514 100644
--- a/Source/WebCore/page/animation/CompositeAnimation.cpp
+++ b/Source/WebCore/page/animation/CompositeAnimation.cpp
@@ -10,7 +10,7 @@
* 2. 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,7 +29,7 @@
#include "config.h"
#include "CompositeAnimation.h"
-#include "AnimationControllerPrivate.h"
+#include "CSSAnimationControllerPrivate.h"
#include "CSSPropertyAnimation.h"
#include "CSSPropertyNames.h"
#include "ImplicitAnimation.h"
@@ -37,14 +37,15 @@
#include "Logging.h"
#include "RenderElement.h"
#include "RenderStyle.h"
+#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>
namespace WebCore {
-CompositeAnimation::CompositeAnimation(AnimationControllerPrivate* animationController)
+CompositeAnimation::CompositeAnimation(CSSAnimationControllerPrivate& animationController)
: m_animationController(animationController)
{
- m_suspended = animationController->isSuspended() && !animationController->allowsNewAnimationsWhileSuspended();
+ m_suspended = m_animationController.isSuspended() && !m_animationController.allowsNewAnimationsWhileSuspended();
}
CompositeAnimation::~CompositeAnimation()
@@ -62,25 +63,21 @@ void CompositeAnimation::clearRenderer()
if (!m_transitions.isEmpty()) {
// Clear the renderers from all running animations, in case we are in the middle of
// an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->value.get();
- animationController()->animationWillBeRemoved(transition);
+ for (auto& transition : m_transitions.values()) {
+ animationController().animationWillBeRemoved(transition.get());
transition->clear();
}
}
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- animationController()->animationWillBeRemoved(anim);
- anim->clear();
+ for (auto& animation : m_keyframeAnimations.values()) {
+ animationController().animationWillBeRemoved(animation.get());
+ animation->clear();
}
}
}
-void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
+void CompositeAnimation::updateTransitions(RenderElement* renderer, const RenderStyle* currentStyle, const RenderStyle* targetStyle)
{
// If currentStyle is null or there are no old or new transitions, just skip it
if (!currentStyle || (!targetStyle->transitions() && m_transitions.isEmpty()))
@@ -88,20 +85,19 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// Mark all existing transitions as no longer active. We will mark the still active ones
// in the next loop and then toss the ones that didn't get marked.
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it)
- it->value->setActive(false);
+ for (auto& transition : m_transitions.values())
+ transition->setActive(false);
- RefPtr<RenderStyle> modifiedCurrentStyle;
+ std::unique_ptr<RenderStyle> modifiedCurrentStyle;
// Check to see if we need to update the active transitions
if (targetStyle->transitions()) {
for (size_t i = 0; i < targetStyle->transitions()->size(); ++i) {
- const Animation& animation = targetStyle->transitions()->animation(i);
+ auto& animation = targetStyle->transitions()->animation(i);
bool isActiveTransition = !m_suspended && (animation.duration() || animation.delay() > 0);
Animation::AnimationMode mode = animation.animationMode();
- if (mode == Animation::AnimateNone)
+ if (mode == Animation::AnimateNone || mode == Animation::AnimateUnknownProperty)
continue;
CSSPropertyID prop = animation.property();
@@ -125,8 +121,8 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// If there is a running animation for this property, the transition is overridden
// and we have to use the unanimatedStyle from the animation. We do the test
// against the unanimated style here, but we "override" the transition later.
- RefPtr<KeyframeAnimation> keyframeAnim = getAnimationForProperty(prop);
- RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle;
+ auto* keyframeAnimation = animationForProperty(prop);
+ auto* fromStyle = keyframeAnimation ? keyframeAnimation->unanimatedStyle() : currentStyle;
// See if there is a current transition for this prop
ImplicitAnimation* implAnim = m_transitions.get(prop);
@@ -148,18 +144,16 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// list. In this case, the latter one overrides the earlier one, so we
// behave as though this is a running animation being replaced.
if (!implAnim->isTargetPropertyEqual(prop, targetStyle)) {
-#if USE(ACCELERATED_COMPOSITING)
// For accelerated animations we need to return a new RenderStyle with the _current_ value
// of the property, so that restarted transitions use the correct starting point.
if (CSSPropertyAnimation::animationOfPropertyIsAccelerated(prop) && implAnim->isAccelerated()) {
if (!modifiedCurrentStyle)
- modifiedCurrentStyle = RenderStyle::clone(currentStyle);
+ modifiedCurrentStyle = RenderStyle::clonePtr(*currentStyle);
implAnim->blendPropertyValueInStyle(prop, modifiedCurrentStyle.get());
}
-#endif
LOG(Animations, "Removing existing ImplicitAnimation %p for property %s", implAnim, getPropertyName(prop));
- animationController()->animationWillBeRemoved(implAnim);
+ animationController().animationWillBeRemoved(implAnim);
m_transitions.remove(prop);
equal = false;
}
@@ -174,11 +168,11 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// <https://bugs.webkit.org/show_bug.cgi?id=24787>
if (!equal && isActiveTransition) {
// Add the new transition
- RefPtr<ImplicitAnimation> implicitAnimation = ImplicitAnimation::create(animation, prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle);
- LOG(Animations, "Created ImplicitAnimation %p for property %s duration %.2f delay %.2f", implicitAnimation.get(), getPropertyName(prop), animation.duration(), animation.delay());
- m_transitions.set(prop, implicitAnimation.release());
+ auto implicitAnimation = ImplicitAnimation::create(animation, prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle);
+ LOG(Animations, "Created ImplicitAnimation %p on renderer %p for property %s duration %.2f delay %.2f", implicitAnimation.ptr(), renderer, getPropertyName(prop), animation.duration(), animation.delay());
+ m_transitions.set(prop, WTFMove(implicitAnimation));
}
-
+
// We only need one pass for the single prop case
if (!all)
break;
@@ -188,158 +182,184 @@ void CompositeAnimation::updateTransitions(RenderElement* renderer, RenderStyle*
// Make a list of transitions to be removed
Vector<int> toBeRemoved;
- end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (!anim->active()) {
- animationController()->animationWillBeRemoved(anim);
- toBeRemoved.append(anim->animatingProperty());
- LOG(Animations, "Removing ImplicitAnimation %p for property %s", anim, getPropertyName(anim->animatingProperty()));
+ for (auto& transition : m_transitions.values()) {
+ if (!transition->active()) {
+ animationController().animationWillBeRemoved(transition.get());
+ toBeRemoved.append(transition->animatingProperty());
+ LOG(Animations, "Removing ImplicitAnimation %p from renderer %p for property %s", transition.get(), renderer, getPropertyName(transition->animatingProperty()));
}
}
// Now remove the transitions from the list
- for (size_t j = 0; j < toBeRemoved.size(); ++j)
- m_transitions.remove(toBeRemoved[j]);
+ for (auto propertyToRemove : toBeRemoved)
+ m_transitions.remove(propertyToRemove);
}
-void CompositeAnimation::updateKeyframeAnimations(RenderElement* renderer, RenderStyle* currentStyle, RenderStyle* targetStyle)
+void CompositeAnimation::updateKeyframeAnimations(RenderElement* renderer, const RenderStyle* currentStyle, const RenderStyle* targetStyle)
{
// Nothing to do if we don't have any animations, and didn't have any before
if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
return;
m_keyframeAnimations.checkConsistency();
+
+ if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations()))
+ return;
+
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ m_hasScrollTriggeredAnimation = false;
+#endif
+
+ AnimationNameMap newAnimations;
+
+ // Toss the animation order map.
+ m_keyframeAnimationOrderMap.clear();
- AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
+ static NeverDestroyed<const AtomicString> none("none", AtomicString::ConstructFromLiteral);
- if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
- // The current and target animations are the same so we just need to toss any
- // animation which is finished (postActive).
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
- if (it->value->postActive())
- it->value->setIndex(-1);
- }
- } else {
- // Mark all existing animations as no longer active.
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
- it->value->setIndex(-1);
+ // Now mark any still active animations as active and add any new animations.
+ if (targetStyle->animations()) {
+ int numAnims = targetStyle->animations()->size();
+ for (int i = 0; i < numAnims; ++i) {
+ auto& animation = targetStyle->animations()->animation(i);
+ AtomicString animationName(animation.name());
+
+ if (!animation.isValidAnimation())
+ continue;
- // Toss the animation order map.
- m_keyframeAnimationOrderMap.clear();
+ // See if there is a current animation for this name.
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
+ if (keyframeAnim) {
+ newAnimations.add(keyframeAnim->name().impl(), keyframeAnim);
- DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
-
- // Now mark any still active animations as active and add any new animations.
- if (targetStyle->animations()) {
- int numAnims = targetStyle->animations()->size();
- for (int i = 0; i < numAnims; ++i) {
- const Animation& animation = targetStyle->animations()->animation(i);
- AtomicString animationName(animation.name());
-
- if (!animation.isValidAnimation())
+ if (keyframeAnim->postActive())
continue;
-
- // See if there is a current animation for this name.
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(animationName.impl());
-
- if (keyframeAnim) {
- // If this animation is postActive, skip it so it gets removed at the end of this function.
- if (keyframeAnim->postActive())
- continue;
-
- // This one is still active.
-
- // Animations match, but play states may differ. Update if needed.
- keyframeAnim->updatePlayState(animation.playState());
-
- // Set the saved animation to this new one, just in case the play state has changed.
- keyframeAnim->setAnimation(animation);
- keyframeAnim->setIndex(i);
- } else if ((animation.duration() || animation.delay()) && animation.iterationCount() && animationName != none) {
- keyframeAnim = KeyframeAnimation::create(animation, renderer, i, this, targetStyle);
- LOG(Animations, "Creating KeyframeAnimation %p with keyframes %s, duration %.2f, delay %.2f, iterations %.2f", keyframeAnim.get(), animation.name().utf8().data(), animation.duration(), animation.delay(), animation.iterationCount());
- if (m_suspended) {
- keyframeAnim->updatePlayState(AnimPlayStatePaused);
- LOG(Animations, " (created in suspended/paused state)");
- }
-#if !LOG_DISABLED
- for (auto it = keyframeAnim->keyframes().beginProperties(), end = keyframeAnim->keyframes().endProperties(); it != end; ++it)
- LOG(Animations, " property %s", getPropertyName(*it));
+
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ if (animation.trigger()->isScrollAnimationTrigger())
+ m_hasScrollTriggeredAnimation = true;
#endif
- m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
+
+ // Animations match, but play states may differ. Update if needed.
+ keyframeAnim->updatePlayState(animation.playState());
+
+ // Set the saved animation to this new one, just in case the play state has changed.
+ keyframeAnim->setAnimation(animation);
+ } else if ((animation.duration() || animation.delay()) && animation.iterationCount() && animationName != none) {
+ keyframeAnim = KeyframeAnimation::create(animation, renderer, this, targetStyle);
+ LOG(Animations, "Creating KeyframeAnimation %p on renderer %p with keyframes %s, duration %.2f, delay %.2f, iterations %.2f", keyframeAnim.get(), renderer, animation.name().utf8().data(), animation.duration(), animation.delay(), animation.iterationCount());
+
+ if (m_suspended) {
+ keyframeAnim->updatePlayState(AnimPlayStatePaused);
+ LOG(Animations, " (created in suspended/paused state)");
}
-
- // Add this to the animation order map.
- if (keyframeAnim)
- m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
+#if !LOG_DISABLED
+ for (auto propertyID : keyframeAnim->keyframes().properties())
+ LOG(Animations, " property %s", getPropertyName(propertyID));
+#endif
+
+#if ENABLE(CSS_ANIMATIONS_LEVEL_2)
+ if (animation.trigger()->isScrollAnimationTrigger())
+ m_hasScrollTriggeredAnimation = true;
+#endif
+
+ newAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
}
+
+ // Add this to the animation order map.
+ if (keyframeAnim)
+ m_keyframeAnimationOrderMap.append(keyframeAnim->name().impl());
}
}
// Make a list of animations to be removed.
- Vector<AtomicStringImpl*> animsToBeRemoved;
- kfend = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
- KeyframeAnimation* keyframeAnim = it->value.get();
- if (keyframeAnim->index() < 0) {
- animsToBeRemoved.append(keyframeAnim->name().impl());
- animationController()->animationWillBeRemoved(keyframeAnim);
- keyframeAnim->clear();
- LOG(Animations, "Removing KeyframeAnimation %p", keyframeAnim);
+ for (auto& animation : m_keyframeAnimations.values()) {
+ if (!newAnimations.contains(animation->name().impl())) {
+ animationController().animationWillBeRemoved(animation.get());
+ animation->clear();
+ LOG(Animations, "Removing KeyframeAnimation %p from renderer %p", animation.get(), renderer);
}
}
- // Now remove the animations from the list.
- for (size_t j = 0; j < animsToBeRemoved.size(); ++j)
- m_keyframeAnimations.remove(animsToBeRemoved[j]);
+ std::swap(newAnimations, m_keyframeAnimations);
}
-PassRef<RenderStyle> CompositeAnimation::animate(RenderElement& renderer, RenderStyle* currentStyle, RenderStyle& targetStyle)
+bool CompositeAnimation::animate(RenderElement& renderer, const RenderStyle* currentStyle, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& blendedStyle)
{
- RefPtr<RenderStyle> resultStyle;
-
// We don't do any transitions if we don't have a currentStyle (on startup).
updateTransitions(&renderer, currentStyle, &targetStyle);
updateKeyframeAnimations(&renderer, currentStyle, &targetStyle);
m_keyframeAnimations.checkConsistency();
+ bool animationStateChanged = false;
+ bool forceStackingContext = false;
+
if (currentStyle) {
// Now that we have transition objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- if (ImplicitAnimation* anim = it->value.get())
- anim->animate(this, &renderer, currentStyle, &targetStyle, resultStyle);
- }
+ bool checkForStackingContext = false;
+ for (auto& transition : m_transitions.values()) {
+ bool didBlendStyle = false;
+ if (transition->animate(this, &renderer, currentStyle, &targetStyle, blendedStyle, didBlendStyle))
+ animationStateChanged = true;
+
+ if (didBlendStyle)
+ checkForStackingContext |= WillChangeData::propertyCreatesStackingContext(transition->animatingProperty());
+ }
+
+ if (blendedStyle && checkForStackingContext) {
+ // Note that this is similar to code in StyleResolver::adjustRenderStyle() but only needs to consult
+ // animatable properties that can trigger stacking context.
+ if (blendedStyle->opacity() < 1.0f
+ || blendedStyle->hasTransformRelatedProperty()
+ || blendedStyle->hasMask()
+ || blendedStyle->clipPath()
+ || blendedStyle->boxReflect()
+ || blendedStyle->hasFilter()
+#if ENABLE(FILTERS_LEVEL_2)
+ || blendedStyle->hasBackdropFilter()
+#endif
+ )
+ forceStackingContext = true;
}
}
// Now that we have animation objects ready, let them know about the new goal state. We want them
// to fill in a RenderStyle*& only if needed.
- for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(*it);
- if (keyframeAnim)
- keyframeAnim->animate(this, &renderer, currentStyle, &targetStyle, resultStyle);
+ for (auto& name : m_keyframeAnimationOrderMap) {
+ RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name);
+ if (keyframeAnim) {
+ bool didBlendStyle = false;
+ if (keyframeAnim->animate(this, &renderer, currentStyle, &targetStyle, blendedStyle, didBlendStyle))
+ animationStateChanged = true;
+
+ forceStackingContext |= didBlendStyle && keyframeAnim->triggersStackingContext();
+ m_hasAnimationThatDependsOnLayout |= keyframeAnim->dependsOnLayout();
+ }
}
- return resultStyle ? resultStyle.releaseNonNull() : targetStyle;
+ // https://drafts.csswg.org/css-animations-1/
+ // While an animation is applied but has not finished, or has finished but has an animation-fill-mode of forwards or both,
+ // the user agent must act as if the will-change property ([css-will-change-1]) on the element additionally
+ // includes all the properties animated by the animation.
+ if (forceStackingContext && blendedStyle) {
+ if (blendedStyle->hasAutoZIndex())
+ blendedStyle->setZIndex(0);
+ }
+
+ return animationStateChanged;
}
-PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
+std::unique_ptr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
{
- RefPtr<RenderStyle> resultStyle;
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- if (ImplicitAnimation* implicitAnimation = it->value.get())
- implicitAnimation->getAnimatedStyle(resultStyle);
- }
+ std::unique_ptr<RenderStyle> resultStyle;
+ for (auto& transition : m_transitions.values())
+ transition->getAnimatedStyle(resultStyle);
m_keyframeAnimations.checkConsistency();
- for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
- RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
+ for (auto& name : m_keyframeAnimationOrderMap) {
+ RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(name);
if (keyframeAnimation)
keyframeAnimation->getAnimatedStyle(resultStyle);
}
@@ -354,10 +374,10 @@ double CompositeAnimation::timeToNextService() const
double minT = -1;
if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->value.get();
- double t = transition ? transition->timeToNextService() : -1;
+ for (auto& transition : m_transitions.values()) {
+ double t = transition->timeToNextService();
+ if (t == -1)
+ continue;
if (t < minT || minT == -1)
minT = t;
if (minT == 0)
@@ -366,10 +386,10 @@ double CompositeAnimation::timeToNextService() const
}
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* animation = it->value.get();
- double t = animation ? animation->timeToNextService() : -1;
+ for (auto& animation : m_keyframeAnimations.values()) {
+ double t = animation->timeToNextService();
+ if (t == -1)
+ continue;
if (t < minT || minT == -1)
minT = t;
if (minT == 0)
@@ -380,23 +400,53 @@ double CompositeAnimation::timeToNextService() const
return minT;
}
-PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(CSSPropertyID property) const
+KeyframeAnimation* CompositeAnimation::animationForProperty(CSSPropertyID property) const
{
- RefPtr<KeyframeAnimation> retval;
-
+ KeyframeAnimation* result = nullptr;
+
// We want to send back the last animation with the property if there are multiples.
// So we need to iterate through all animations
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- RefPtr<KeyframeAnimation> anim = it->value;
- if (anim->hasAnimationForProperty(property))
- retval = anim;
+ for (auto& animation : m_keyframeAnimations.values()) {
+ if (animation->hasAnimationForProperty(property))
+ result = animation.get();
}
}
+
+ return result;
+}
+
+bool CompositeAnimation::computeExtentOfTransformAnimation(LayoutRect& bounds) const
+{
+ // If more than one transition and animation affect transform, give up.
+ bool seenTransformAnimation = false;
+
+ for (auto& animation : m_keyframeAnimations.values()) {
+ if (!animation->hasAnimationForProperty(CSSPropertyTransform))
+ continue;
+
+ if (seenTransformAnimation)
+ return false;
+
+ seenTransformAnimation = true;
+
+ if (!animation->computeExtentOfTransformAnimation(bounds))
+ return false;
+ }
+
+ for (auto& transition : m_transitions.values()) {
+ if (transition->animatingProperty() != CSSPropertyTransform || !transition->hasStyle())
+ continue;
+
+ if (seenTransformAnimation)
+ return false;
+
+ if (!transition->computeExtentOfTransformAnimation(bounds))
+ return false;
+ }
- return retval;
+ return true;
}
void CompositeAnimation::suspendAnimations()
@@ -408,18 +458,14 @@ void CompositeAnimation::suspendAnimations()
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- if (KeyframeAnimation* anim = it->value.get())
- anim->updatePlayState(AnimPlayStatePaused);
- }
+ for (auto& animation : m_keyframeAnimations.values())
+ animation->updatePlayState(AnimPlayStatePaused);
}
+
if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->hasStyle())
- anim->updatePlayState(AnimPlayStatePaused);
+ for (auto& transition : m_transitions.values()) {
+ if (transition->hasStyle())
+ transition->updatePlayState(AnimPlayStatePaused);
}
}
}
@@ -433,32 +479,26 @@ void CompositeAnimation::resumeAnimations()
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- if (anim && anim->playStatePlaying())
- anim->updatePlayState(AnimPlayStatePlaying);
+ for (auto& animation : m_keyframeAnimations.values()) {
+ if (animation->playStatePlaying())
+ animation->updatePlayState(AnimPlayStatePlaying);
}
}
if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->hasStyle())
- anim->updatePlayState(AnimPlayStatePlaying);
+ for (auto& transition : m_transitions.values()) {
+ if (transition->hasStyle())
+ transition->updatePlayState(AnimPlayStatePlaying);
}
}
}
void CompositeAnimation::overrideImplicitAnimations(CSSPropertyID property)
{
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
if (!m_transitions.isEmpty()) {
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->animatingProperty() == property)
- anim->setOverridden(true);
+ for (auto& transition : m_transitions.values()) {
+ if (transition->animatingProperty() == property)
+ transition->setOverridden(true);
}
}
}
@@ -466,32 +506,26 @@ void CompositeAnimation::overrideImplicitAnimations(CSSPropertyID property)
void CompositeAnimation::resumeOverriddenImplicitAnimations(CSSPropertyID property)
{
if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->animatingProperty() == property)
- anim->setOverridden(false);
+ for (auto& transition : m_transitions.values()) {
+ if (transition->animatingProperty() == property)
+ transition->setOverridden(false);
}
}
}
-bool CompositeAnimation::isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, bool isRunningNow) const
+bool CompositeAnimation::isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, AnimationBase::RunningState runningState) const
{
if (!m_keyframeAnimations.isEmpty()) {
m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow))
+ for (auto& animation : m_keyframeAnimations.values()) {
+ if (animation->isAnimatingProperty(property, acceleratedOnly, runningState))
return true;
}
}
if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow))
+ for (auto& transition : m_transitions.values()) {
+ if (transition->isAnimatingProperty(property, acceleratedOnly, runningState))
return true;
}
}
@@ -506,13 +540,8 @@ bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t
if (!keyframeAnim || !keyframeAnim->running())
return false;
- double count = keyframeAnim->m_animation->iterationCount();
- if ((t >= 0.0) && ((count == Animation::IterationCountInfinite) || (t <= count * keyframeAnim->duration()))) {
- keyframeAnim->freezeAtTime(t);
- return true;
- }
-
- return false;
+ keyframeAnim->freezeAtTime(t);
+ return true;
}
bool CompositeAnimation::pauseTransitionAtTime(CSSPropertyID property, double t)
@@ -526,9 +555,8 @@ bool CompositeAnimation::pauseTransitionAtTime(CSSPropertyID property, double t)
// This code is only used for testing, so performance is not critical here.
HashSet<CSSPropertyID> shorthandProperties = CSSPropertyAnimation::animatableShorthandsAffectingProperty(property);
bool anyPaused = false;
- HashSet<CSSPropertyID>::const_iterator end = shorthandProperties.end();
- for (HashSet<CSSPropertyID>::const_iterator it = shorthandProperties.begin(); it != end; ++it) {
- if (pauseTransitionAtTime(*it, t))
+ for (auto propertyID : shorthandProperties) {
+ if (pauseTransitionAtTime(propertyID, t))
anyPaused = true;
}
return anyPaused;
@@ -549,23 +577,15 @@ unsigned CompositeAnimation::numberOfActiveAnimations() const
{
unsigned count = 0;
- if (!m_keyframeAnimations.isEmpty()) {
- m_keyframeAnimations.checkConsistency();
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- if (anim->running())
- ++count;
- }
+ m_keyframeAnimations.checkConsistency();
+ for (auto& animation : m_keyframeAnimations.values()) {
+ if (animation->running())
+ ++count;
}
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim->running())
- ++count;
- }
+ for (auto& transition : m_transitions.values()) {
+ if (transition->running())
+ ++count;
}
return count;