Merge from Chromium at DEPS revision 269336
This commit was generated by merge_to_master.py.
Change-Id: Ibf41f59c608fa0127526255ada8e255a93306a7e
diff --git a/Source/core/animation/ActiveAnimations.cpp b/Source/core/animation/ActiveAnimations.cpp
index e12cbdc..3509885 100644
--- a/Source/core/animation/ActiveAnimations.cpp
+++ b/Source/core/animation/ActiveAnimations.cpp
@@ -37,10 +37,6 @@
ActiveAnimations::~ActiveAnimations()
{
-}
-
-void ActiveAnimations::dispose()
-{
for (size_t i = 0; i < m_animations.size(); ++i)
m_animations[i]->notifyElementDestroyed();
m_animations.clear();
@@ -96,6 +92,9 @@
void ActiveAnimations::trace(Visitor* visitor)
{
visitor->trace(m_cssAnimations);
+#if ENABLE(OILPAN)
+ visitor->trace(m_target);
+#endif
}
} // namespace WebCore
diff --git a/Source/core/animation/ActiveAnimations.h b/Source/core/animation/ActiveAnimations.h
index 1a4c0a0..966f73c 100644
--- a/Source/core/animation/ActiveAnimations.h
+++ b/Source/core/animation/ActiveAnimations.h
@@ -53,7 +53,6 @@
}
~ActiveAnimations();
- void dispose();
// Animations that are currently active for this element, their effects will be applied
// during a style recalc. CSS Transitions are included in this stack.
@@ -94,6 +93,16 @@
// won't be needed once Element and Animation are moved to Oilpan.
Vector<Animation*> m_animations;
+#if ENABLE(OILPAN)
+ // Keep a back reference to the target Element, so that this object
+ // will be finalized during the same GC sweep as the target (as the
+ // Element keeps a reference in the other direction via its
+ // rare data.) This is done so that we can accurately notify the
+ // the Element as destroyed to the above vector of Animations in
+ // the ActiveAnimations finalizer.
+ Member<Element> m_target;
+#endif
+
// CSSAnimations checks if a style change is due to animation.
friend class CSSAnimations;
};
diff --git a/Source/core/animation/AnimatableClipPathOperation.h b/Source/core/animation/AnimatableClipPathOperation.h
index 2cffa78..0a0188d 100644
--- a/Source/core/animation/AnimatableClipPathOperation.h
+++ b/Source/core/animation/AnimatableClipPathOperation.h
@@ -45,7 +45,7 @@
}
ClipPathOperation* clipPathOperation() const { return m_operation.get(); }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableColor.h b/Source/core/animation/AnimatableColor.h
index 5723248..87196a0 100644
--- a/Source/core/animation/AnimatableColor.h
+++ b/Source/core/animation/AnimatableColor.h
@@ -62,7 +62,7 @@
Color color() const { return m_color.toColor(); }
Color visitedLinkColor() const { return m_visitedLinkColor.toColor(); }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableDouble.cpp b/Source/core/animation/AnimatableDouble.cpp
index eaadd00..b27e515 100644
--- a/Source/core/animation/AnimatableDouble.cpp
+++ b/Source/core/animation/AnimatableDouble.cpp
@@ -31,18 +31,11 @@
#include "config.h"
#include "core/animation/AnimatableDouble.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSValuePool.h"
#include "platform/animation/AnimationUtilities.h"
#include <math.h>
namespace WebCore {
-PassRefPtrWillBeRawPtr<CSSValue> AnimatableDouble::toCSSValue() const
-{
- return cssValuePool().createValue(m_number, CSSPrimitiveValue::CSS_NUMBER);
-}
-
bool AnimatableDouble::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
const AnimatableDouble* other = toAnimatableDouble(value);
diff --git a/Source/core/animation/AnimatableDouble.h b/Source/core/animation/AnimatableDouble.h
index 0d6496a..88ef247 100644
--- a/Source/core/animation/AnimatableDouble.h
+++ b/Source/core/animation/AnimatableDouble.h
@@ -32,7 +32,6 @@
#define AnimatableDouble_h
#include "core/animation/AnimatableValue.h"
-#include "core/css/CSSValue.h"
namespace WebCore {
@@ -50,10 +49,9 @@
return adoptRefWillBeNoop(new AnimatableDouble(number, constraint));
}
- PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const;
double toDouble() const { return m_number; }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableDoubleTest.cpp b/Source/core/animation/AnimatableDoubleTest.cpp
index 1f6e8cc..f1948fb 100644
--- a/Source/core/animation/AnimatableDoubleTest.cpp
+++ b/Source/core/animation/AnimatableDoubleTest.cpp
@@ -31,8 +31,6 @@
#include "config.h"
#include "core/animation/AnimatableDouble.h"
-#include "core/css/CSSPrimitiveValue.h"
-
#include <gtest/gtest.h>
using namespace WebCore;
@@ -51,14 +49,6 @@
EXPECT_FALSE(AnimatableDouble::create(5)->equals(AnimatableDouble::create(10).get()));
}
-TEST(AnimationAnimatableDoubleTest, ToCSSValue)
-{
- RefPtrWillBeRawPtr<CSSValue> cssValue5 = CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_NUMBER);
- RefPtrWillBeRawPtr<CSSValue> cssValue10 = CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_NUMBER);
- EXPECT_TRUE(AnimatableDouble::create(5)->toCSSValue()->equals(*cssValue5.get()));
- EXPECT_FALSE(AnimatableDouble::create(5)->toCSSValue()->equals(*cssValue10.get()));
-}
-
TEST(AnimationAnimatableDoubleTest, ToDouble)
{
EXPECT_EQ(5.9, AnimatableDouble::create(5.9)->toDouble());
diff --git a/Source/core/animation/AnimatableFilterOperations.h b/Source/core/animation/AnimatableFilterOperations.h
index 569d694..e047201 100644
--- a/Source/core/animation/AnimatableFilterOperations.h
+++ b/Source/core/animation/AnimatableFilterOperations.h
@@ -45,7 +45,7 @@
}
const FilterOperations& operations() const { return m_operations; }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableImage.h b/Source/core/animation/AnimatableImage.h
index c7e535c..e76b619 100644
--- a/Source/core/animation/AnimatableImage.h
+++ b/Source/core/animation/AnimatableImage.h
@@ -46,7 +46,11 @@
}
CSSValue* toCSSValue() const { return m_value.get(); }
- virtual void trace(Visitor* visitor) OVERRIDE { visitor->trace(m_value); }
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_value);
+ AnimatableValue::trace(visitor);
+ }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableLength.cpp b/Source/core/animation/AnimatableLength.cpp
index fcc2668..c167c20 100644
--- a/Source/core/animation/AnimatableLength.cpp
+++ b/Source/core/animation/AnimatableLength.cpp
@@ -31,127 +31,53 @@
#include "config.h"
#include "core/animation/AnimatableLength.h"
-#include "core/css/CSSPrimitiveValueMappings.h"
#include "platform/CalculationValue.h"
#include "platform/animation/AnimationUtilities.h"
namespace WebCore {
-PassRefPtrWillBeRawPtr<AnimatableLength> AnimatableLength::create(CSSValue* value)
+namespace {
+
+double clampNumber(double value, ValueRange range)
{
- ASSERT(canCreateFrom(value));
- if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value);
- const CSSCalcValue* calcValue = primitiveValue->cssCalcValue();
- if (calcValue)
- return create(calcValue->expressionNode(), primitiveValue);
- CSSPrimitiveValue::LengthUnitType unitType;
- bool isPrimitiveLength = CSSPrimitiveValue::unitTypeToLengthUnitType(primitiveValue->primitiveType(), unitType);
- ASSERT_UNUSED(isPrimitiveLength, isPrimitiveLength);
- const double scale = CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(primitiveValue->primitiveType());
- return create(primitiveValue->getDoubleValue() * scale, unitType, primitiveValue);
- }
-
- if (value->isCalcValue())
- return create(toCSSCalcValue(value)->expressionNode());
-
- ASSERT_NOT_REACHED();
- return nullptr;
+ if (range == ValueRangeNonNegative)
+ return std::max(value, 0.0);
+ ASSERT(range == ValueRangeAll);
+ return value;
}
-bool AnimatableLength::canCreateFrom(const CSSValue* value)
-{
- ASSERT(value);
- if (value->isPrimitiveValue()) {
- const CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value);
- if (primitiveValue->cssCalcValue())
- return true;
+} // namespace
- CSSPrimitiveValue::LengthUnitType type;
- // Only returns true if the type is a primitive length unit.
- return CSSPrimitiveValue::unitTypeToLengthUnitType(primitiveValue->primitiveType(), type);
- }
- return value->isCalcValue();
+AnimatableLength::AnimatableLength(const Length& length, float zoom)
+{
+ ASSERT(zoom);
+ PixelsAndPercent pixelsAndPercent = length.pixelsAndPercent();
+ m_pixels = pixelsAndPercent.pixels / zoom;
+ m_percent = pixelsAndPercent.percent;
+ m_hasPixels = length.type() != Percent;
+ m_hasPercent = !length.isFixed();
}
-PassRefPtrWillBeRawPtr<CSSValue> AnimatableLength::toCSSValue(NumberRange range) const
+Length AnimatableLength::length(float zoom, ValueRange range) const
{
- return toCSSPrimitiveValue(range);
-}
-
-Length AnimatableLength::toLength(const CSSToLengthConversionData& conversionData, NumberRange range) const
-{
- // Avoid creating a CSSValue in the common cases
- if (m_lengthUnitType == CSSPrimitiveValue::UnitTypePixels)
- return Length(clampedNumber(range) * conversionData.zoom(), Fixed);
- if (m_lengthUnitType == CSSPrimitiveValue::UnitTypePercentage)
- return Length(clampedNumber(range), Percent);
-
- return toCSSPrimitiveValue(range)->convertToLength<AnyConversion>(conversionData);
+ if (!m_hasPercent)
+ return Length(clampNumber(m_pixels, range) * zoom, Fixed);
+ if (!m_hasPixels)
+ return Length(clampNumber(m_percent, range), Percent);
+ return Length(CalculationValue::create(PixelsAndPercent(m_pixels * zoom, m_percent), range));
}
PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLength::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableLength* length = toAnimatableLength(value);
- CSSPrimitiveValue::LengthUnitType type = commonUnitType(length);
- if (!isCalc(type))
- return AnimatableLength::create(blend(m_lengthValue, length->m_lengthValue, fraction), type);
- return AnimatableLength::create(scale(1 - fraction).get(), length->scale(fraction).get());
+ return create(blend(m_pixels, length->m_pixels, fraction), blend(m_percent, length->m_percent, fraction),
+ m_hasPixels || length->m_hasPixels, m_hasPercent || length->m_hasPercent);
}
bool AnimatableLength::equalTo(const AnimatableValue* value) const
{
const AnimatableLength* length = toAnimatableLength(value);
- if (m_lengthUnitType != length->m_lengthUnitType)
- return false;
- if (isCalc())
- return m_calcExpression == length->m_calcExpression || m_calcExpression->equals(*length->m_calcExpression);
- return m_lengthValue == length->m_lengthValue;
-}
-
-PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> AnimatableLength::toCSSCalcExpressionNode() const
-{
- if (isCalc())
- return m_calcExpression;
- return CSSCalcValue::createExpressionNode(toCSSPrimitiveValue(AllValues), m_lengthValue == trunc(m_lengthValue));
-}
-
-static bool isCompatibleWithRange(const CSSPrimitiveValue* primitiveValue, NumberRange range)
-{
- ASSERT(primitiveValue);
- if (range == AllValues)
- return true;
- if (primitiveValue->isCalculated())
- return primitiveValue->cssCalcValue()->permittedValueRange() == ValueRangeNonNegative;
- return primitiveValue->getDoubleValue() >= 0;
-}
-
-PassRefPtrWillBeRawPtr<CSSPrimitiveValue> AnimatableLength::toCSSPrimitiveValue(NumberRange range) const
-{
- if (!m_cachedCSSPrimitiveValue || !isCompatibleWithRange(m_cachedCSSPrimitiveValue.get(), range)) {
- if (isCalc())
- m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(CSSCalcValue::create(m_calcExpression, range == AllValues ? ValueRangeAll : ValueRangeNonNegative));
- else
- m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(clampedNumber(range), static_cast<CSSPrimitiveValue::UnitTypes>(CSSPrimitiveValue::lengthUnitTypeToUnitType(m_lengthUnitType)));
- }
- return m_cachedCSSPrimitiveValue;
-}
-
-PassRefPtrWillBeRawPtr<AnimatableLength> AnimatableLength::scale(double factor) const
-{
- if (isCalc()) {
- return AnimatableLength::create(CSSCalcValue::createExpressionNode(
- m_calcExpression,
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(factor, CSSPrimitiveValue::CSS_NUMBER)),
- CalcMultiply));
- }
- return AnimatableLength::create(m_lengthValue * factor, m_lengthUnitType);
-}
-
-void AnimatableLength::trace(Visitor* visitor)
-{
- visitor->trace(m_calcExpression);
- visitor->trace(m_cachedCSSPrimitiveValue);
+ return m_pixels == length->m_pixels && m_percent == length->m_percent && m_hasPixels == length->m_hasPixels && m_hasPercent == length->m_hasPercent;
}
} // namespace WebCore
diff --git a/Source/core/animation/AnimatableLength.h b/Source/core/animation/AnimatableLength.h
index adfb136..754c043 100644
--- a/Source/core/animation/AnimatableLength.h
+++ b/Source/core/animation/AnimatableLength.h
@@ -32,109 +32,44 @@
#define AnimatableLength_h
#include "core/animation/AnimatableValue.h"
-#include "core/css/CSSCalculationValue.h"
-#include "core/css/CSSPrimitiveValue.h"
#include "platform/Length.h"
namespace WebCore {
-enum NumberRange {
- AllValues,
- NonNegativeValues,
-};
-
-// Handles animation of CSS length and percentage values including CSS calc.
-// See primitiveUnitToLengthType() for the list of supported units.
-// If created from a CSSPrimitiveValue this class will cache it to be returned in toCSSValue().
class AnimatableLength FINAL : public AnimatableValue {
public:
- virtual ~AnimatableLength() { }
- static bool canCreateFrom(const CSSValue*);
- static PassRefPtrWillBeRawPtr<AnimatableLength> create(CSSValue*);
- static PassRefPtrWillBeRawPtr<AnimatableLength> create(double number, CSSPrimitiveValue::LengthUnitType unitType, CSSPrimitiveValue* cssPrimitiveValue = 0)
+ static PassRefPtrWillBeRawPtr<AnimatableLength> create(const Length& length, float zoom)
{
- return adoptRefWillBeNoop(new AnimatableLength(number, unitType, cssPrimitiveValue));
+ return adoptRefWillBeNoop(new AnimatableLength(length, zoom));
}
- static PassRefPtrWillBeRawPtr<AnimatableLength> create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> calcExpression, CSSPrimitiveValue* cssPrimitiveValue = 0)
- {
- return adoptRefWillBeNoop(new AnimatableLength(calcExpression, cssPrimitiveValue));
- }
- PassRefPtrWillBeRawPtr<CSSValue> toCSSValue(NumberRange = AllValues) const;
- Length toLength(const CSSToLengthConversionData&, NumberRange = AllValues) const;
-
- virtual void trace(Visitor*) OVERRIDE;
+ Length length(float zoom, ValueRange) const;
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
- AnimatableLength(double number, CSSPrimitiveValue::LengthUnitType unitType, CSSPrimitiveValue* cssPrimitiveValue)
- : m_lengthValue(number)
- , m_lengthUnitType(unitType)
- , m_cachedCSSPrimitiveValue(cssPrimitiveValue)
+ static PassRefPtrWillBeRawPtr<AnimatableLength> create(double pixels, double percent, bool hasPixels, bool hasPercent)
{
- ASSERT(!isCalc());
+ return adoptRefWillBeNoop(new AnimatableLength(pixels, percent, hasPixels, hasPercent));
}
- AnimatableLength(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> calcExpression, CSSPrimitiveValue* cssPrimitiveValue)
- : m_lengthUnitType(CSSPrimitiveValue::UnitTypeCalc)
- , m_calcExpression(calcExpression)
- , m_cachedCSSPrimitiveValue(cssPrimitiveValue)
+ AnimatableLength(const Length&, float zoom);
+ AnimatableLength(double pixels, double percent, bool hasPixels, bool hasPercent)
+ : m_pixels(pixels)
+ , m_percent(percent)
+ , m_hasPixels(hasPixels)
+ , m_hasPercent(hasPercent)
{
- ASSERT(isCalc());
- ASSERT(m_calcExpression);
+ ASSERT(m_hasPixels || m_hasPercent);
}
virtual AnimatableType type() const OVERRIDE { return TypeLength; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- static bool isCalc(CSSPrimitiveValue::LengthUnitType type) { return type == CSSPrimitiveValue::UnitTypeCalc; }
- bool isCalc() const { return isCalc(m_lengthUnitType); }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
- static PassRefPtrWillBeRawPtr<AnimatableLength> create(const AnimatableLength* leftAddend, const AnimatableLength* rightAddend)
- {
- ASSERT(leftAddend && rightAddend);
- return create(CSSCalcValue::createExpressionNode(leftAddend->toCSSCalcExpressionNode(), rightAddend->toCSSCalcExpressionNode(), CalcAdd));
- }
-
- PassRefPtrWillBeRawPtr<CSSPrimitiveValue> toCSSPrimitiveValue(NumberRange) const;
- PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> toCSSCalcExpressionNode() const;
-
- PassRefPtrWillBeRawPtr<AnimatableLength> scale(double) const;
- double clampedNumber(NumberRange range) const
- {
- ASSERT(!isCalc());
- return (range == NonNegativeValues && m_lengthValue <= 0) ? 0 : m_lengthValue;
- }
-
- // Zero is effectively unitless, except in the case of percentage.
- // http://www.w3.org/TR/css3-values/#calc-computed-value
- // e.g. calc(100% - 100% + 1em) resolves to calc(0% + 1em), not to calc(1em)
- bool isUnitlessZero() const
- {
- return !isCalc() && !m_lengthValue && m_lengthUnitType != CSSPrimitiveValue::UnitTypePercentage;
- }
-
- CSSPrimitiveValue::LengthUnitType commonUnitType(const AnimatableLength* length) const
- {
- if (m_lengthUnitType == length->m_lengthUnitType)
- return m_lengthUnitType;
-
- if (isUnitlessZero())
- return length->m_lengthUnitType;
- if (length->isUnitlessZero())
- return m_lengthUnitType;
-
- return CSSPrimitiveValue::UnitTypeCalc;
- }
-
- double m_lengthValue;
- const CSSPrimitiveValue::LengthUnitType m_lengthUnitType;
-
- RefPtrWillBeMember<CSSCalcExpressionNode> m_calcExpression;
-
- mutable RefPtrWillBeMember<CSSPrimitiveValue> m_cachedCSSPrimitiveValue;
-
- friend class AnimationAnimatableLengthTest;
- friend class LengthStyleInterpolation;
+ double m_pixels;
+ double m_percent;
+ bool m_hasPixels;
+ bool m_hasPercent;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableLength, isLength());
diff --git a/Source/core/animation/AnimatableLengthBox.cpp b/Source/core/animation/AnimatableLengthBox.cpp
index ebf760e..2589621 100644
--- a/Source/core/animation/AnimatableLengthBox.cpp
+++ b/Source/core/animation/AnimatableLengthBox.cpp
@@ -58,6 +58,7 @@
visitor->trace(m_right);
visitor->trace(m_top);
visitor->trace(m_bottom);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/Source/core/animation/AnimatableLengthBoxAndBool.cpp b/Source/core/animation/AnimatableLengthBoxAndBool.cpp
index 8aec4d7..c598ec4 100644
--- a/Source/core/animation/AnimatableLengthBoxAndBool.cpp
+++ b/Source/core/animation/AnimatableLengthBoxAndBool.cpp
@@ -61,6 +61,7 @@
void AnimatableLengthBoxAndBool::trace(Visitor* visitor)
{
visitor->trace(m_box);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/Source/core/animation/AnimatableLengthPoint.cpp b/Source/core/animation/AnimatableLengthPoint.cpp
index e47279e..b8805d0 100644
--- a/Source/core/animation/AnimatableLengthPoint.cpp
+++ b/Source/core/animation/AnimatableLengthPoint.cpp
@@ -51,6 +51,7 @@
{
visitor->trace(m_x);
visitor->trace(m_y);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/Source/core/animation/AnimatableLengthPoint3D.cpp b/Source/core/animation/AnimatableLengthPoint3D.cpp
index da031a3..402f0a8 100644
--- a/Source/core/animation/AnimatableLengthPoint3D.cpp
+++ b/Source/core/animation/AnimatableLengthPoint3D.cpp
@@ -53,6 +53,7 @@
visitor->trace(m_x);
visitor->trace(m_y);
visitor->trace(m_z);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/Source/core/animation/AnimatableLengthSize.cpp b/Source/core/animation/AnimatableLengthSize.cpp
index 79f52e1..c632395 100644
--- a/Source/core/animation/AnimatableLengthSize.cpp
+++ b/Source/core/animation/AnimatableLengthSize.cpp
@@ -51,6 +51,7 @@
{
visitor->trace(m_width);
visitor->trace(m_height);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/Source/core/animation/AnimatableLengthTest.cpp b/Source/core/animation/AnimatableLengthTest.cpp
index 48d8ec6..c5887e2 100644
--- a/Source/core/animation/AnimatableLengthTest.cpp
+++ b/Source/core/animation/AnimatableLengthTest.cpp
@@ -1,318 +1,73 @@
-/*
- * 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.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "config.h"
#include "core/animation/AnimatableLength.h"
-
-#include "core/animation/AnimatableValueTestHelper.h"
-#include "core/css/CSSCalculationValue.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSToLengthConversionData.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "core/rendering/style/StyleInheritedData.h"
#include "platform/CalculationValue.h"
-#include "wtf/MathExtras.h"
#include <gtest/gtest.h>
-#define EXPECT_ROUNDTRIP(a, f) EXPECT_REFV_EQ(a, f(a.get()))
-
namespace WebCore {
-class AnimationAnimatableLengthTest : public ::testing::Test {
-protected:
- AnimationAnimatableLengthTest()
- : style(RenderStyle::createDefaultStyle())
- , conversionDataZoom1(style.get(), style.get(), 0, 0, 1.0f)
- , conversionDataZoom3(style.get(), style.get(), 0, 0, 3.0f)
+namespace {
+
+ PassRefPtrWillBeRawPtr<AnimatableLength> create(const Length& length, double zoom = 1)
{
+ return AnimatableLength::create(length, zoom);
}
- PassRefPtrWillBeRawPtr<AnimatableLength> create(double value, CSSPrimitiveValue::UnitTypes type)
- {
- return AnimatableLength::create(CSSPrimitiveValue::create(value, type).get());
- }
+} // namespace
- PassRefPtrWillBeRawPtr<AnimatableLength> create(double valueLeft, CSSPrimitiveValue::UnitTypes typeLeft, double valueRight, CSSPrimitiveValue::UnitTypes typeRight)
- {
- return AnimatableLength::create(createCalc(valueLeft, typeLeft, valueRight, typeRight).get());
- }
-
- PassRefPtrWillBeRawPtr<CSSCalcValue> createCalc(double valueLeft, CSSPrimitiveValue::UnitTypes typeLeft, double valueRight, CSSPrimitiveValue::UnitTypes typeRight)
- {
- return CSSCalcValue::create(CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(valueLeft, typeLeft), valueLeft == trunc(valueLeft)),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(valueRight, typeRight), valueRight == trunc(valueRight)),
- CalcAdd
- ));
- }
-
- PassRefPtrWillBeRawPtr<CSSValue> toCSSValue(CSSValue* cssValue)
- {
- return AnimatableLength::create(cssValue)->toCSSValue();
- }
-
- CSSPrimitiveValue::LengthUnitType commonUnitType(PassRefPtrWillBeRawPtr<AnimatableLength> a, PassRefPtrWillBeRawPtr<AnimatableLength> b)
- {
- return a->commonUnitType(b.get());
- }
-
- bool isUnitlessZero(PassRefPtrWillBeRawPtr<AnimatableLength> a)
- {
- return a->isUnitlessZero();
- }
-
- RefPtr<RenderStyle> style;
- CSSToLengthConversionData conversionDataZoom1;
- CSSToLengthConversionData conversionDataZoom3;
-};
-
-TEST_F(AnimationAnimatableLengthTest, CanCreateFrom)
+TEST(AnimationAnimatableLengthTest, RoundTripConversion)
{
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_MM).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_IN).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PT).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PC).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_EXS).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VW).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VH).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VMIN).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VMAX).get()));
-
- EXPECT_TRUE(AnimatableLength::canCreateFrom(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM)).get()));
-
- EXPECT_FALSE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create("NaN", CSSPrimitiveValue::CSS_STRING).get()));
+ EXPECT_EQ(Length(0, Fixed), create(Length(0, Fixed))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(0, Percent), create(Length(0, Percent))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(10, Fixed), create(Length(10, Fixed))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(10, Percent), create(Length(10, Percent))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(-10, Fixed), create(Length(-10, Fixed))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(-10, Percent), create(Length(-10, Percent))->length(1, ValueRangeAll));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(5, 10), ValueRangeAll));
+ EXPECT_EQ(calc, create(calc)->length(1, ValueRangeAll));
}
-TEST_F(AnimationAnimatableLengthTest, Create)
+TEST(AnimationAnimatableLengthTest, ValueRangeNonNegative)
{
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_MM).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_IN).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PT).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PC).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_EXS).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VW).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VH).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VMIN).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VMAX).get()));
-
- EXPECT_TRUE(static_cast<bool>(
- AnimatableLength::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()).get()
- ));
- EXPECT_TRUE(static_cast<bool>(
- AnimatableLength::create(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM)).get()).get()
- ));
+ EXPECT_EQ(Length(10, Fixed), create(Length(10, Fixed))->length(1, ValueRangeNonNegative));
+ EXPECT_EQ(Length(10, Percent), create(Length(10, Percent))->length(1, ValueRangeNonNegative));
+ EXPECT_EQ(Length(0, Fixed), create(Length(-10, Fixed))->length(1, ValueRangeNonNegative));
+ EXPECT_EQ(Length(0, Percent), create(Length(-10, Percent))->length(1, ValueRangeNonNegative));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(-5, -10), ValueRangeNonNegative));
+ EXPECT_TRUE(calc == create(calc)->length(1, ValueRangeNonNegative));
}
-
-TEST_F(AnimationAnimatableLengthTest, ToCSSValue)
+TEST(AnimationAnimatableLengthTest, Zoom)
{
-
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PX), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_CM), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_MM), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_IN), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PT), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PC), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_EMS), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_EXS), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_REMS), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PERCENTAGE), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VW), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VH), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VMIN), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VMAX), toCSSValue);
-
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_IN)), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_IN)), toCSSValue);
+ EXPECT_EQ(Length(4, Fixed), create(Length(10, Fixed), 5)->length(2, ValueRangeAll));
+ EXPECT_EQ(Length(10, Percent), create(Length(10, Percent), 5)->length(2, ValueRangeAll));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(5, 10), ValueRangeAll));
+ Length result = Length(CalculationValue::create(PixelsAndPercent(2, 10), ValueRangeAll));
+ EXPECT_TRUE(result == create(calc, 5)->length(2, ValueRangeAll));
}
-
-TEST_F(AnimationAnimatableLengthTest, ToLength)
+TEST(AnimationAnimatableLengthTest, Equals)
{
- EXPECT_EQ(Length(-5, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom1));
- EXPECT_EQ(Length(-15, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom3));
- EXPECT_EQ(Length(0, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom1, NonNegativeValues));
- EXPECT_EQ(Length(0, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom3, NonNegativeValues));
-
- EXPECT_EQ(Length(-5, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1));
- EXPECT_EQ(Length(-5, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3));
- EXPECT_EQ(Length(0, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1, NonNegativeValues));
- EXPECT_EQ(Length(0, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3, NonNegativeValues));
-
- EXPECT_EQ(
- Length(CalculationValue::create(PixelsAndPercent(-5, -5), ValueRangeAll)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1));
- EXPECT_EQ(
- Length(CalculationValue::create(PixelsAndPercent(-15, -5), ValueRangeAll)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3));
- EXPECT_EQ(
- Length(CalculationValue::create(PixelsAndPercent(-5, -5), ValueRangeNonNegative)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1, NonNegativeValues));
- EXPECT_EQ(
- Length(CalculationValue::create(PixelsAndPercent(-15, -5), ValueRangeNonNegative)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3, NonNegativeValues));
+ EXPECT_TRUE(create(Length(10, Fixed))->equals(create(Length(10, Fixed)).get()));
+ EXPECT_TRUE(create(Length(20, Percent))->equals(create(Length(20, Percent)).get()));
+ EXPECT_FALSE(create(Length(10, Fixed))->equals(create(Length(10, Percent)).get()));
+ EXPECT_FALSE(create(Length(0, Percent))->equals(create(Length(0, Fixed)).get()));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(5, 10), ValueRangeAll));
+ EXPECT_TRUE(create(calc)->equals(create(calc).get()));
+ EXPECT_FALSE(create(calc)->equals(create(Length(10, Percent)).get()));
}
-TEST_F(AnimationAnimatableLengthTest, Interpolate)
+TEST(AnimationAnimatableLengthTest, Interpolate)
{
- RefPtrWillBeRawPtr<AnimatableLength> from10px = create(10, CSSPrimitiveValue::CSS_PX);
- RefPtrWillBeRawPtr<AnimatableLength> to20pxAsInches = create(20.0 / 96, CSSPrimitiveValue::CSS_IN);
-
- EXPECT_REFV_EQ(create(5, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), -0.5));
-
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0));
- EXPECT_REFV_EQ(create(14, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0.4));
- EXPECT_REFV_EQ(create(15, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0.5));
- EXPECT_REFV_EQ(create(16, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0.6));
- EXPECT_REFV_EQ(create(20.0 / 96, CSSPrimitiveValue::CSS_IN),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 1));
- EXPECT_REFV_EQ(create(25, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 1.5));
-
- RefPtrWillBeRawPtr<AnimatableLength> from10em = create(10, CSSPrimitiveValue::CSS_EMS);
- RefPtrWillBeRawPtr<AnimatableLength> to20rem = create(20, CSSPrimitiveValue::CSS_REMS);
- EXPECT_REFV_EQ(create(15, CSSPrimitiveValue::CSS_EMS, -10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), -0.5));
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_EMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0));
- EXPECT_REFV_EQ(create(6, CSSPrimitiveValue::CSS_EMS, 8, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0.4));
- EXPECT_REFV_EQ(create(5, CSSPrimitiveValue::CSS_EMS, 10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0.5));
- EXPECT_REFV_EQ(create(4, CSSPrimitiveValue::CSS_EMS, 12, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0.6));
- EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 1));
- EXPECT_REFV_EQ(create(-5, CSSPrimitiveValue::CSS_EMS, 30, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 1.5));
-
- // Zero values are typeless and hence we can don't get a calc
- RefPtrWillBeRawPtr<AnimatableLength> from0px = create(0, CSSPrimitiveValue::CSS_PX);
- EXPECT_REFV_EQ(create(-10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), -0.5));
- // At t=0, interpolate always returns the "from" value.
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 0));
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 0.5));
- EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 1.0));
- EXPECT_REFV_EQ(create(30, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 1.5));
-
- // Except 0% which is special
- RefPtrWillBeRawPtr<AnimatableLength> from0percent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, -10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), -0.5));
- // At t=0, interpolate always returns the "from" value.
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 0));
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, 10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 0.5));
- // At t=1, interpolate always returns the "to" value.
- EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 1.0));
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, 30, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 1.5));
-}
-
-TEST_F(AnimationAnimatableLengthTest, IsUnitless)
-{
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_PX)));
- EXPECT_FALSE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_PERCENTAGE)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_EMS)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_EXS)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_REMS)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VW)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VH)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VMIN)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VMAX)));
-
- EXPECT_FALSE(isUnitlessZero(create(1, CSSPrimitiveValue::CSS_PX)));
- EXPECT_FALSE(isUnitlessZero(create(2, CSSPrimitiveValue::CSS_PERCENTAGE)));
- EXPECT_FALSE(isUnitlessZero(create(3, CSSPrimitiveValue::CSS_EMS)));
- EXPECT_FALSE(isUnitlessZero(create(4, CSSPrimitiveValue::CSS_EXS)));
- EXPECT_FALSE(isUnitlessZero(create(5, CSSPrimitiveValue::CSS_REMS)));
- EXPECT_FALSE(isUnitlessZero(create(6, CSSPrimitiveValue::CSS_VW)));
- EXPECT_FALSE(isUnitlessZero(create(7, CSSPrimitiveValue::CSS_VH)));
- EXPECT_FALSE(isUnitlessZero(create(8, CSSPrimitiveValue::CSS_VMIN)));
- EXPECT_FALSE(isUnitlessZero(create(9, CSSPrimitiveValue::CSS_VMAX)));
-}
-
-TEST_F(AnimationAnimatableLengthTest, CommonUnitType)
-{
- RefPtrWillBeRawPtr<AnimatableLength> length10px = create(10, CSSPrimitiveValue::CSS_PX);
- EXPECT_EQ(CSSPrimitiveValue::UnitTypePixels, commonUnitType(length10px, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length10px, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length10px, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length10px, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length10px, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
-
- RefPtrWillBeRawPtr<AnimatableLength> length0px = create(0, CSSPrimitiveValue::CSS_PX);
- EXPECT_EQ(CSSPrimitiveValue::UnitTypePixels, commonUnitType(length0px, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypePercentage, commonUnitType(length0px, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeFontSize, commonUnitType(length0px, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length0px, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypePercentage, commonUnitType(length0px, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
-
- RefPtrWillBeRawPtr<AnimatableLength> length0percent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length0percent, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypePercentage, commonUnitType(length0percent, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length0percent, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(length0percent, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypePercentage, commonUnitType(length0percent, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
-
- RefPtrWillBeRawPtr<AnimatableLength> lengthCalc = create(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM);
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(lengthCalc, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(lengthCalc, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(lengthCalc, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(lengthCalc, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(CSSPrimitiveValue::UnitTypeCalc, commonUnitType(lengthCalc, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
+ EXPECT_TRUE(AnimatableValue::interpolate(create(Length(10, Fixed)).get(), create(Length(0, Fixed)).get(), 0.2)->equals(create(Length(8, Fixed)).get()));
+ EXPECT_TRUE(AnimatableValue::interpolate(create(Length(4, Percent)).get(), create(Length(12, Percent)).get(), 0.25)->equals(create(Length(6, Percent)).get()));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(12, 4), ValueRangeAll));
+ EXPECT_TRUE(AnimatableValue::interpolate(create(Length(20, Fixed)).get(), create(Length(10, Percent)).get(), 0.4)->equals(create(calc).get()));
}
} // namespace WebCore
diff --git a/Source/core/animation/AnimatableNeutral.h b/Source/core/animation/AnimatableNeutral.h
index 30b5cb7..16f8595 100644
--- a/Source/core/animation/AnimatableNeutral.h
+++ b/Source/core/animation/AnimatableNeutral.h
@@ -39,7 +39,7 @@
public:
virtual ~AnimatableNeutral() { }
- virtual void trace(Visitor* visitor) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
static PassRefPtrWillBeRawPtr<AnimatableNeutral> create() { return adoptRefWillBeNoop(new AnimatableNeutral()); }
diff --git a/Source/core/animation/AnimatableRepeatable.cpp b/Source/core/animation/AnimatableRepeatable.cpp
index f732f1f..72a4166 100644
--- a/Source/core/animation/AnimatableRepeatable.cpp
+++ b/Source/core/animation/AnimatableRepeatable.cpp
@@ -105,6 +105,7 @@
void AnimatableRepeatable::trace(Visitor* visitor)
{
visitor->trace(m_values);
+ AnimatableValue::trace(visitor);
}
} // namespace WebCore
diff --git a/Source/core/animation/AnimatableSVGLength.h b/Source/core/animation/AnimatableSVGLength.h
index d390fd4..5b7f791 100644
--- a/Source/core/animation/AnimatableSVGLength.h
+++ b/Source/core/animation/AnimatableSVGLength.h
@@ -50,7 +50,7 @@
return m_length.get();
}
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableSVGPaint.h b/Source/core/animation/AnimatableSVGPaint.h
index 6a08ac6..c098e1f 100644
--- a/Source/core/animation/AnimatableSVGPaint.h
+++ b/Source/core/animation/AnimatableSVGPaint.h
@@ -52,7 +52,7 @@
Color color() const { return m_color.toColor(); };
const String& uri() const { return m_uri; };
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableShadow.h b/Source/core/animation/AnimatableShadow.h
index 146c858..80a7cf5 100644
--- a/Source/core/animation/AnimatableShadow.h
+++ b/Source/core/animation/AnimatableShadow.h
@@ -45,7 +45,7 @@
}
ShadowList* shadowList() const { return m_shadowList.get(); }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableShapeValue.h b/Source/core/animation/AnimatableShapeValue.h
index 4306b29..decc6f3 100644
--- a/Source/core/animation/AnimatableShapeValue.h
+++ b/Source/core/animation/AnimatableShapeValue.h
@@ -45,7 +45,7 @@
}
ShapeValue* shapeValue() const { return m_shape.get(); }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableStrokeDasharrayList.cpp b/Source/core/animation/AnimatableStrokeDasharrayList.cpp
index 5d4ff29..f81e351 100644
--- a/Source/core/animation/AnimatableStrokeDasharrayList.cpp
+++ b/Source/core/animation/AnimatableStrokeDasharrayList.cpp
@@ -75,11 +75,7 @@
if (from.isEmpty() && to.isEmpty())
return takeConstRef(this);
if (from.isEmpty() || to.isEmpty()) {
-#if ENABLE_OILPAN
- DEFINE_STATIC_LOCAL(Persistent<AnimatableSVGLength>, zeroPixels, (AnimatableSVGLength::create(SVGLength::create())));
-#else
- DEFINE_STATIC_REF(AnimatableSVGLength, zeroPixels, AnimatableSVGLength::create(SVGLength::create()).leakRef());
-#endif
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(AnimatableSVGLength, zeroPixels, (AnimatableSVGLength::create(SVGLength::create())));
if (from.isEmpty()) {
from.append(zeroPixels);
from.append(zeroPixels);
diff --git a/Source/core/animation/AnimatableTransform.h b/Source/core/animation/AnimatableTransform.h
index 18164de..51896af 100644
--- a/Source/core/animation/AnimatableTransform.h
+++ b/Source/core/animation/AnimatableTransform.h
@@ -45,7 +45,7 @@
return m_transform;
}
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimatableUnknown.h b/Source/core/animation/AnimatableUnknown.h
index c310416..a483910 100644
--- a/Source/core/animation/AnimatableUnknown.h
+++ b/Source/core/animation/AnimatableUnknown.h
@@ -56,6 +56,7 @@
virtual void trace(Visitor* visitor) OVERRIDE
{
visitor->trace(m_value);
+ AnimatableValue::trace(visitor);
}
protected:
diff --git a/Source/core/animation/AnimatableValue.cpp b/Source/core/animation/AnimatableValue.cpp
index 4176a8e..af0aec9 100644
--- a/Source/core/animation/AnimatableValue.cpp
+++ b/Source/core/animation/AnimatableValue.cpp
@@ -44,13 +44,8 @@
const AnimatableValue* AnimatableValue::neutralValue()
{
-#if ENABLE_OILPAN
- DEFINE_STATIC_LOCAL(Persistent<AnimatableNeutral>, neutralSentinelValue, (AnimatableNeutral::create()));
- return neutralSentinelValue.get();
-#else
- DEFINE_STATIC_REF(AnimatableNeutral, neutralSentinelValue, (AnimatableNeutral::create()));
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(AnimatableNeutral, neutralSentinelValue, (AnimatableNeutral::create()));
return neutralSentinelValue;
-#endif
}
PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableValue::interpolate(const AnimatableValue* left, const AnimatableValue* right, double fraction)
diff --git a/Source/core/animation/AnimatableValue.h b/Source/core/animation/AnimatableValue.h
index 6f59146..2306142 100644
--- a/Source/core/animation/AnimatableValue.h
+++ b/Source/core/animation/AnimatableValue.h
@@ -87,7 +87,7 @@
return value->type() == type();
}
- virtual void trace(Visitor*) = 0;
+ virtual void trace(Visitor*) { }
protected:
enum AnimatableType {
diff --git a/Source/core/animation/AnimatableValueKeyframe.cpp b/Source/core/animation/AnimatableValueKeyframe.cpp
index 75b146b..b131b0e 100644
--- a/Source/core/animation/AnimatableValueKeyframe.cpp
+++ b/Source/core/animation/AnimatableValueKeyframe.cpp
@@ -74,6 +74,7 @@
void AnimatableValueKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor)
{
visitor->trace(m_value);
+ Keyframe::PropertySpecificKeyframe::trace(visitor);
}
}
diff --git a/Source/core/animation/AnimatableValueTestHelper.cpp b/Source/core/animation/AnimatableValueTestHelper.cpp
index 66c2d09..c3f4a60 100644
--- a/Source/core/animation/AnimatableValueTestHelper.cpp
+++ b/Source/core/animation/AnimatableValueTestHelper.cpp
@@ -51,52 +51,11 @@
<< animColor.visitedLinkColor().serialized().utf8().data() << ")";
}
-void PrintTo(const AnimatableDouble& animDouble, ::std::ostream* os)
-{
- PrintTo(*(animDouble.toCSSValue().get()), os, "AnimatableDouble");
-}
-
void PrintTo(const AnimatableImage& animImage, ::std::ostream* os)
{
PrintTo(*(animImage.toCSSValue()), os, "AnimatableImage");
}
-void PrintTo(const AnimatableLength& animLength, ::std::ostream* os)
-{
- PrintTo(*(animLength.toCSSValue().get()), os, "AnimatableLength");
-}
-
-void PrintTo(const AnimatableLengthBox& animLengthBox, ::std::ostream* os)
-{
- *os << "AnimatableLengthBox(";
- PrintTo(*(animLengthBox.left()), os);
- *os << ", ";
- PrintTo(*(animLengthBox.right()), os);
- *os << ", ";
- PrintTo(*(animLengthBox.top()), os);
- *os << ", ";
- PrintTo(*(animLengthBox.bottom()), os);
- *os << ")";
-}
-
-void PrintTo(const AnimatableLengthPoint& animLengthPoint, ::std::ostream* os)
-{
- *os << "AnimatableLengthPoint(";
- PrintTo(*(animLengthPoint.x()), os);
- *os << ", ";
- PrintTo(*(animLengthPoint.y()), os);
- *os << ")";
-}
-
-void PrintTo(const AnimatableLengthSize& animLengthSize, ::std::ostream* os)
-{
- *os << "AnimatableLengthSize(";
- PrintTo(*(animLengthSize.width()), os);
- *os << ", ";
- PrintTo(*(animLengthSize.height()), os);
- *os << ")";
-}
-
void PrintTo(const AnimatableNeutral& animValue, ::std::ostream* os)
{
*os << "AnimatableNeutral@" << &animValue;
@@ -231,18 +190,8 @@
PrintTo(*(toAnimatableClipPathOperation(&animValue)), os);
else if (animValue.isColor())
PrintTo(*(toAnimatableColor(&animValue)), os);
- else if (animValue.isDouble())
- PrintTo(*(toAnimatableDouble(&animValue)), os);
else if (animValue.isImage())
PrintTo(*(toAnimatableImage(&animValue)), os);
- else if (animValue.isLength())
- PrintTo(*(toAnimatableLength(&animValue)), os);
- else if (animValue.isLengthBox())
- PrintTo(*(toAnimatableLengthBox(&animValue)), os);
- else if (animValue.isLengthPoint())
- PrintTo(*(toAnimatableLengthPoint(&animValue)), os);
- else if (animValue.isLengthSize())
- PrintTo(*(toAnimatableLengthSize(&animValue)), os);
else if (animValue.isNeutral())
PrintTo(*(static_cast<const AnimatableNeutral*>(&animValue)), os);
else if (animValue.isRepeatable())
diff --git a/Source/core/animation/AnimatableValueTestHelper.h b/Source/core/animation/AnimatableValueTestHelper.h
index 65a8660..bff27ed 100644
--- a/Source/core/animation/AnimatableValueTestHelper.h
+++ b/Source/core/animation/AnimatableValueTestHelper.h
@@ -38,12 +38,7 @@
#include "core/animation/AnimatableClipPathOperation.h"
#include "core/animation/AnimatableColor.h"
-#include "core/animation/AnimatableDouble.h"
#include "core/animation/AnimatableImage.h"
-#include "core/animation/AnimatableLength.h"
-#include "core/animation/AnimatableLengthBox.h"
-#include "core/animation/AnimatableLengthPoint.h"
-#include "core/animation/AnimatableLengthSize.h"
#include "core/animation/AnimatableNeutral.h"
#include "core/animation/AnimatableRepeatable.h"
#include "core/animation/AnimatableSVGLength.h"
@@ -68,12 +63,7 @@
void PrintTo(const AnimatableClipPathOperation&, ::std::ostream*);
void PrintTo(const AnimatableColor&, ::std::ostream*);
-void PrintTo(const AnimatableDouble&, ::std::ostream*);
void PrintTo(const AnimatableImage&, ::std::ostream*);
-void PrintTo(const AnimatableLength&, ::std::ostream*);
-void PrintTo(const AnimatableLengthBox&, ::std::ostream*);
-void PrintTo(const AnimatableLengthPoint&, ::std::ostream*);
-void PrintTo(const AnimatableLengthSize&, ::std::ostream*);
void PrintTo(const AnimatableNeutral&, ::std::ostream*);
void PrintTo(const AnimatableRepeatable&, ::std::ostream*);
void PrintTo(const AnimatableSVGLength&, ::std::ostream*);
diff --git a/Source/core/animation/AnimatableValueTestHelperTest.cpp b/Source/core/animation/AnimatableValueTestHelperTest.cpp
index 6ae5965..f1d1c22 100644
--- a/Source/core/animation/AnimatableValueTestHelperTest.cpp
+++ b/Source/core/animation/AnimatableValueTestHelperTest.cpp
@@ -67,48 +67,10 @@
::std::string("AnimatableColor(rgba(0, 0, 0, 0), #ff0000)"),
PrintToString(AnimatableColor::create(Color(0x000000FF), Color(0xFFFF0000))));
- EXPECT_EQ(
- ::std::string("AnimatableDouble(1)"),
- PrintToString(AnimatableDouble::create(1.0)));
-
- EXPECT_EQ(
- ::std::string("AnimatableLength(5px)"),
- PrintToString(AnimatableLength::create(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PX).get())));
-
- EXPECT_EQ(
- ::std::string("AnimatableLengthBox(AnimatableLength(1px), AnimatableLength(2em), AnimatableLength(3rem), AnimatableLength(4pt))"),
- PrintToString(AnimatableLengthBox::create(
- AnimatableLength::create(CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_PX).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(2, CSSPrimitiveValue::CSS_EMS).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(3, CSSPrimitiveValue::CSS_REMS).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(4, CSSPrimitiveValue::CSS_PT).get())
- )));
-
- EXPECT_EQ(
- ::std::string("AnimatableLengthPoint(AnimatableLength(5%), AnimatableLength(6px))"),
- PrintToString(AnimatableLengthPoint::create(
- AnimatableLength::create(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(6, CSSPrimitiveValue::CSS_PX).get())
- )));
-
- EXPECT_EQ(
- ::std::string("AnimatableLengthSize(AnimatableLength(3rem), AnimatableLength(4pt))"),
- PrintToString(AnimatableLengthSize::create(
- AnimatableLength::create(CSSPrimitiveValue::create(3, CSSPrimitiveValue::CSS_REMS).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(4, CSSPrimitiveValue::CSS_PT).get())
- )));
-
EXPECT_THAT(
PrintToString(const_cast<AnimatableValue*>(AnimatableValue::neutralValue())),
testing::StartsWith("AnimatableNeutral@"));
- WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > v1;
- v1.append(AnimatableLength::create(CSSPrimitiveValue::create(3, CSSPrimitiveValue::CSS_REMS).get()));
- v1.append(AnimatableLength::create(CSSPrimitiveValue::create(4, CSSPrimitiveValue::CSS_PT).get()));
- EXPECT_EQ(
- ::std::string("AnimatableRepeatable(AnimatableLength(3rem), AnimatableLength(4pt))"),
- PrintToString(AnimatableRepeatable::create(v1)));
-
RefPtr<SVGLength> length1cm = SVGLength::create(LengthModeOther);
RefPtr<SVGLength> length2cm = SVGLength::create(LengthModeOther);
length1cm->setValueAsString("1cm", ASSERT_NO_EXCEPTION);
diff --git a/Source/core/animation/AnimatableVisibility.h b/Source/core/animation/AnimatableVisibility.h
index 2b344b3..72d653e 100644
--- a/Source/core/animation/AnimatableVisibility.h
+++ b/Source/core/animation/AnimatableVisibility.h
@@ -46,7 +46,7 @@
EVisibility visibility() const { return m_visibility; }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
protected:
virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
diff --git a/Source/core/animation/AnimationClock.cpp b/Source/core/animation/AnimationClock.cpp
index 6492206..304136c 100644
--- a/Source/core/animation/AnimationClock.cpp
+++ b/Source/core/animation/AnimationClock.cpp
@@ -28,26 +28,54 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <math.h>
#include "config.h"
#include "core/animation/AnimationClock.h"
+#include "wtf/CurrentTime.h"
+
+namespace {
+
+// FIXME: This is an approximation of time between frames, used when
+// ticking the animation clock outside of animation frame callbacks.
+// Ideally this would be generated by the compositor.
+const double approximateFrameTime = 1 / 60.0;
+
+}
namespace WebCore {
+unsigned AnimationClock::s_currentTask = 0;
+
void AnimationClock::updateTime(double time)
{
if (time > m_time)
m_time = time;
- m_frozen = true;
+ m_currentTask = s_currentTask;
}
double AnimationClock::currentTime()
{
- if (!m_frozen) {
- double newTime = m_monotonicallyIncreasingTime();
- if (newTime >= m_time + minTimeBeforeUnsynchronizedAnimationClockTick)
- m_time = newTime;
+ if (m_currentTask != s_currentTask) {
+ const double currentTime = m_monotonicallyIncreasingTime();
+ if (m_time < currentTime) {
+ // Advance to the first estimated frame after the current time.
+ const double frameShift = fmod(currentTime - m_time, approximateFrameTime);
+ const double newTime = currentTime + approximateFrameTime - frameShift;
+ ASSERT(newTime > currentTime);
+ ASSERT(newTime <= currentTime + approximateFrameTime);
+ updateTime(newTime);
+ } else {
+ m_currentTask = s_currentTask;
+ }
}
return m_time;
}
+void AnimationClock::resetTimeForTesting()
+{
+ m_time = 0;
+ m_currentTask = 0;
+ s_currentTask = 0;
+}
+
}
diff --git a/Source/core/animation/AnimationClock.h b/Source/core/animation/AnimationClock.h
index 540dfbe..e5a3bdb 100644
--- a/Source/core/animation/AnimationClock.h
+++ b/Source/core/animation/AnimationClock.h
@@ -31,40 +31,34 @@
#ifndef AnimationClock_h
#define AnimationClock_h
+#include <limits>
#include "wtf/CurrentTime.h"
#include "wtf/PassOwnPtr.h"
+#include "wtf/Noncopyable.h"
namespace WebCore {
-// FIXME: This value is used to suppress updates when time is required outside of a frame.
-// The purpose of allowing the clock to update during such periods is to allow animations
-// to have an appropriate start time and for getComputedStyle to attempt to catch-up to a
-// compositor animation. However a more accurate system might be to attempt to phase-lock
-// with the frame clock.
-const double minTimeBeforeUnsynchronizedAnimationClockTick = 0.005;
-
class AnimationClock {
+ WTF_MAKE_NONCOPYABLE(AnimationClock);
public:
- static PassOwnPtr<AnimationClock> create(WTF::TimeFunction monotonicallyIncreasingTime = WTF::monotonicallyIncreasingTime)
+ explicit AnimationClock(WTF::TimeFunction monotonicallyIncreasingTime = WTF::monotonicallyIncreasingTime)
+ : m_monotonicallyIncreasingTime(monotonicallyIncreasingTime)
+ , m_time(0)
+ , m_currentTask(std::numeric_limits<unsigned>::max())
{
- return adoptPtr(new AnimationClock(monotonicallyIncreasingTime));
}
void updateTime(double time);
double currentTime();
- void unfreeze() { m_frozen = false; }
- void resetTimeForTesting() { m_time = 0; m_frozen = true; }
+ void resetTimeForTesting();
+
+ static void notifyTaskStart() { ++s_currentTask; }
private:
- AnimationClock(WTF::TimeFunction monotonicallyIncreasingTime)
- : m_monotonicallyIncreasingTime(monotonicallyIncreasingTime)
- , m_time(0)
- , m_frozen(false)
- {
- }
WTF::TimeFunction m_monotonicallyIncreasingTime;
double m_time;
- bool m_frozen;
+ unsigned m_currentTask;
+ static unsigned s_currentTask;
};
} // namespace WebCore
diff --git a/Source/core/animation/AnimationClockTest.cpp b/Source/core/animation/AnimationClockTest.cpp
index 7e54cde..2823fb1 100644
--- a/Source/core/animation/AnimationClockTest.cpp
+++ b/Source/core/animation/AnimationClockTest.cpp
@@ -39,11 +39,15 @@
namespace {
class AnimationAnimationClockTest : public ::testing::Test {
+public:
+ AnimationAnimationClockTest()
+ : animationClock(mockTimeFunction)
+ {}
protected:
virtual void SetUp()
{
- animationClock = AnimationClock::create(mockTimeFunction);
- mockTime = 200;
+ mockTime = 0;
+ animationClock.resetTimeForTesting();
}
static double mockTimeFunction()
@@ -52,36 +56,88 @@
}
static double mockTime;
- OwnPtr<AnimationClock> animationClock;
+ AnimationClock animationClock;
};
double AnimationAnimationClockTest::mockTime;
-TEST_F(AnimationAnimationClockTest, CurrentTime)
+TEST_F(AnimationAnimationClockTest, TimeIsGreaterThanZeroForUnitTests)
{
- // Current time should not advance until minTimeBeforeUnsynchronizedTick has elapsed
- EXPECT_EQ(200, animationClock->currentTime());
- mockTime = 200 + minTimeBeforeUnsynchronizedAnimationClockTick / 2.0;
- EXPECT_EQ(200, animationClock->currentTime());
-
- mockTime = 200 + minTimeBeforeUnsynchronizedAnimationClockTick;
- EXPECT_EQ(mockTime, animationClock->currentTime());
+ AnimationClock clock;
+ // unit tests outside core/animation shouldn't need to do anything to get
+ // a non-zero currentTime().
+ EXPECT_GT(clock.currentTime(), 0);
}
-TEST_F(AnimationAnimationClockTest, UpdateTime)
+TEST_F(AnimationAnimationClockTest, TimeDoesNotChange)
{
- animationClock->updateTime(100);
- EXPECT_EQ(100, animationClock->currentTime());
- mockTime = 200;
- EXPECT_EQ(100, animationClock->currentTime());
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+ EXPECT_EQ(100, animationClock.currentTime());
+}
- animationClock->unfreeze();
- EXPECT_EQ(200, animationClock->currentTime());
+TEST_F(AnimationAnimationClockTest, TimeAdvancesWhenUpdated)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
- animationClock->updateTime(300);
- EXPECT_EQ(300, animationClock->currentTime());
- mockTime = 400;
- EXPECT_EQ(300, animationClock->currentTime());
+ animationClock.updateTime(200);
+ EXPECT_EQ(200, animationClock.currentTime());
+}
+
+TEST_F(AnimationAnimationClockTest, TimeAdvancesToTaskTime)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 150;
+ AnimationClock::notifyTaskStart();
+ EXPECT_GE(animationClock.currentTime(), mockTime);
+}
+
+TEST_F(AnimationAnimationClockTest, TimeAdvancesToTaskTimeOnlyWhenRequired)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ AnimationClock::notifyTaskStart();
+ animationClock.updateTime(125);
+ EXPECT_EQ(125, animationClock.currentTime());
+}
+
+TEST_F(AnimationAnimationClockTest, UpdateTimeIsMonotonic)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ // Update can't go backwards.
+ animationClock.updateTime(50);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 50;
+ AnimationClock::notifyTaskStart();
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 150;
+ AnimationClock::notifyTaskStart();
+ EXPECT_GE(animationClock.currentTime(), mockTime);
+
+ // Update can't go backwards after advance to estimate.
+ animationClock.updateTime(100);
+ EXPECT_GE(animationClock.currentTime(), mockTime);
+}
+
+TEST_F(AnimationAnimationClockTest, CurrentTimeUpdatesTask)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 100;
+ AnimationClock::notifyTaskStart();
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 150;
+ EXPECT_EQ(100, animationClock.currentTime());
}
}
diff --git a/Source/core/animation/AnimationEffect.h b/Source/core/animation/AnimationEffect.h
index f55c8aa..42441e9 100644
--- a/Source/core/animation/AnimationEffect.h
+++ b/Source/core/animation/AnimationEffect.h
@@ -54,7 +54,7 @@
virtual bool affects(CSSPropertyID) { return false; };
virtual bool isKeyframeEffectModel() const { return false; }
- virtual void trace(Visitor*) = 0;
+ virtual void trace(Visitor*) { }
};
} // namespace WebCore
diff --git a/Source/core/animation/AnimationPlayer.cpp b/Source/core/animation/AnimationPlayer.cpp
index 7abd43f..545a737 100644
--- a/Source/core/animation/AnimationPlayer.cpp
+++ b/Source/core/animation/AnimationPlayer.cpp
@@ -64,7 +64,7 @@
, m_paused(false)
, m_held(false)
, m_isPausedForTesting(false)
- , m_outdated(false)
+ , m_outdated(true)
, m_finished(false)
{
if (m_content) {
@@ -173,17 +173,22 @@
if (newStartTime == m_startTime)
return;
updateCurrentTimingState(); // Update the value of held
+ bool hadStartTime = hasStartTime();
+ double previousCurrentTime = currentTimeInternal();
m_startTime = newStartTime;
m_sortInfo.m_startTime = newStartTime;
- if (!isUpdateFromCompositor)
- cancelAnimationOnCompositor();
- if (isUpdateFromCompositor || !m_held)
- setOutdated();
- if (m_held)
- return;
updateCurrentTimingState();
- if (!isUpdateFromCompositor)
+ if (previousCurrentTime != currentTimeInternal()) {
+ setOutdated();
+ } else if (!hadStartTime && m_timeline) {
+ // Even though this player is not outdated, time to effect change is
+ // infinity until start time is set.
+ m_timeline->wake();
+ }
+ if (!isUpdateFromCompositor) {
+ cancelAnimationOnCompositor();
schedulePendingAnimationOnCompositor();
+ }
}
void AnimationPlayer::setSource(TimedItem* newSource)
@@ -344,7 +349,7 @@
toAnimation(m_content.get())->cancelAnimationOnCompositor();
}
-bool AnimationPlayer::update(UpdateReason reason)
+bool AnimationPlayer::update(TimingUpdateReason reason)
{
m_outdated = false;
@@ -353,20 +358,18 @@
if (m_content) {
double inheritedTime = isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal();
- m_content->updateInheritedTime(inheritedTime);
+ m_content->updateInheritedTime(inheritedTime, reason);
}
if (finished() && !m_finished) {
- const AtomicString& eventType = EventTypeNames::finish;
- if (executionContext() && hasEventListeners(eventType)) {
- if (reason == UpdateForAnimationFrame) {
+ if (reason == TimingUpdateForAnimationFrame && hasStartTime()) {
+ const AtomicString& eventType = EventTypeNames::finish;
+ if (executionContext() && hasEventListeners(eventType)) {
RefPtrWillBeRawPtr<AnimationPlayerEvent> event = AnimationPlayerEvent::create(eventType, currentTime(), timeline()->currentTime());
event->setTarget(this);
event->setCurrentTarget(this);
m_timeline->document()->enqueueAnimationFrameEvent(event.release());
- m_finished = true;
}
- } else {
m_finished = true;
}
}
diff --git a/Source/core/animation/AnimationPlayer.h b/Source/core/animation/AnimationPlayer.h
index 35d6777..c542533 100644
--- a/Source/core/animation/AnimationPlayer.h
+++ b/Source/core/animation/AnimationPlayer.h
@@ -43,16 +43,12 @@
class AnimationPlayer FINAL : public RefCounted<AnimationPlayer>, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(AnimationPlayer);
public:
- enum UpdateReason {
- UpdateOnDemand,
- UpdateForAnimationFrame
- };
~AnimationPlayer();
static PassRefPtr<AnimationPlayer> create(DocumentTimeline&, TimedItem*);
// Returns whether the player is finished.
- bool update(UpdateReason);
+ bool update(TimingUpdateReason);
// timeToEffectChange returns:
// infinity - if this player is no longer in effect
@@ -74,6 +70,9 @@
void reverse();
void finish(ExceptionState&);
bool finished() { return limited(currentTimeInternal()); }
+ // FIXME: Resolve whether finished() should just return the flag, and
+ // remove this method.
+ bool finishedInternal() const { return m_finished; }
DEFINE_ATTRIBUTE_EVENT_LISTENER(finish);
diff --git a/Source/core/animation/AnimationPlayerTest.cpp b/Source/core/animation/AnimationPlayerTest.cpp
index 6bb18cf..713af2d 100644
--- a/Source/core/animation/AnimationPlayerTest.cpp
+++ b/Source/core/animation/AnimationPlayerTest.cpp
@@ -80,7 +80,7 @@
{
document->animationClock().updateTime(time);
// The timeline does not know about our player, so we have to explicitly call update().
- return player->update(AnimationPlayer::UpdateOnDemand);
+ return player->update(TimingUpdateOnDemand);
}
RefPtr<Document> document;
@@ -599,6 +599,7 @@
TEST_F(AnimationAnimationPlayerTest, EmptyAnimationPlayersDontUpdateEffects)
{
player = timeline->createAnimationPlayer(0);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
updateTimeline(1234);
@@ -643,24 +644,24 @@
EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
player->setCurrentTimeInternal(0);
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(1, player->timeToEffectChange());
player->setPlaybackRate(2);
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(0.5, player->timeToEffectChange());
player->setPlaybackRate(0);
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
player->setCurrentTimeInternal(3);
player->setPlaybackRate(-1);
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(1, player->timeToEffectChange());
player->setPlaybackRate(-2);
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(0.5, player->timeToEffectChange());
}
@@ -668,7 +669,7 @@
{
EXPECT_EQ(0, player->timeToEffectChange());
player->pause();
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
}
@@ -678,7 +679,7 @@
player->setCurrentTimeInternal(-8);
player->setPlaybackRate(2);
player->cancel();
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(4, player->timeToEffectChange());
}
@@ -688,7 +689,7 @@
player->setCurrentTimeInternal(9);
player->setPlaybackRate(-3);
player->cancel();
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
EXPECT_EQ(3, player->timeToEffectChange());
}
@@ -699,11 +700,11 @@
Timing timing;
RefPtr<Animation> animation = Animation::create(element.get(), nullptr, timing);
RefPtr<AnimationPlayer> player = timeline->createAnimationPlayer(animation.get());
- timeline->serviceAnimations(AnimationPlayer::UpdateForAnimationFrame);
+ player->setStartTime(0);
+ timeline->serviceAnimations(TimingUpdateForAnimationFrame);
EXPECT_EQ(1, element->activeAnimations()->players().find(player.get())->value);
player.release();
- EXPECT_EQ(0, element->activeAnimations()->players().find(player.get())->value);
EXPECT_TRUE(element->activeAnimations()->players().isEmpty());
}
diff --git a/Source/core/animation/AnimationStackTest.cpp b/Source/core/animation/AnimationStackTest.cpp
index 7d44ce4..e28259b 100644
--- a/Source/core/animation/AnimationStackTest.cpp
+++ b/Source/core/animation/AnimationStackTest.cpp
@@ -29,14 +29,14 @@
{
AnimationPlayer* player = timeline->createAnimationPlayer(animation);
player->setStartTimeInternal(startTime);
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
return player;
}
void updateTimeline(double time)
{
document->animationClock().updateTime(time);
- timeline->serviceAnimations(AnimationPlayer::UpdateOnDemand);
+ timeline->serviceAnimations(TimingUpdateForAnimationFrame);
}
const Vector<OwnPtr<SampledEffect> >& effects()
diff --git a/Source/core/animation/AnimationTest.cpp b/Source/core/animation/AnimationTest.cpp
index ca3dc6f..c16c5ec 100644
--- a/Source/core/animation/AnimationTest.cpp
+++ b/Source/core/animation/AnimationTest.cpp
@@ -6,7 +6,6 @@
#include "core/animation/Animation.h"
#include "bindings/v8/Dictionary.h"
-#include "core/animation/AnimatableLength.h"
#include "core/animation/AnimationClock.h"
#include "core/animation/AnimationHelpers.h"
#include "core/animation/AnimationTestHelper.h"
diff --git a/Source/core/animation/DocumentAnimations.cpp b/Source/core/animation/DocumentAnimations.cpp
index 9ea1c6b..7fe6e3e 100644
--- a/Source/core/animation/DocumentAnimations.cpp
+++ b/Source/core/animation/DocumentAnimations.cpp
@@ -46,7 +46,7 @@
namespace {
-void updateAnimationTiming(Document& document, AnimationPlayer::UpdateReason reason)
+void updateAnimationTiming(Document& document, TimingUpdateReason reason)
{
document.timeline().serviceAnimations(reason);
document.transitionTimeline().serviceAnimations(reason);
@@ -57,13 +57,13 @@
void DocumentAnimations::updateAnimationTimingForAnimationFrame(Document& document, double monotonicAnimationStartTime)
{
document.animationClock().updateTime(monotonicAnimationStartTime);
- updateAnimationTiming(document, AnimationPlayer::UpdateForAnimationFrame);
+ updateAnimationTiming(document, TimingUpdateForAnimationFrame);
}
void DocumentAnimations::updateOutdatedAnimationPlayersIfNeeded(Document& document)
{
if (needsOutdatedAnimationPlayerUpdate(document))
- updateAnimationTiming(document, AnimationPlayer::UpdateOnDemand);
+ updateAnimationTiming(document, TimingUpdateOnDemand);
}
void DocumentAnimations::updateAnimationTimingForGetComputedStyle(Node& node, CSSPropertyID property)
@@ -75,7 +75,7 @@
if ((property == CSSPropertyOpacity && style->isRunningOpacityAnimationOnCompositor())
|| ((property == CSSPropertyTransform || property == CSSPropertyWebkitTransform) && style->isRunningTransformAnimationOnCompositor())
|| (property == CSSPropertyWebkitFilter && style->isRunningFilterAnimationOnCompositor())) {
- updateAnimationTiming(element.document(), AnimationPlayer::UpdateOnDemand);
+ updateAnimationTiming(element.document(), TimingUpdateOnDemand);
}
}
}
@@ -92,8 +92,6 @@
ASSERT(document.view());
document.view()->scheduleAnimation();
}
-
- document.animationClock().unfreeze();
}
} // namespace WebCore
diff --git a/Source/core/animation/DocumentTimeline.cpp b/Source/core/animation/DocumentTimeline.cpp
index fd815cf..f989159 100644
--- a/Source/core/animation/DocumentTimeline.cpp
+++ b/Source/core/animation/DocumentTimeline.cpp
@@ -92,12 +92,11 @@
m_timing->serviceOnNextFrame();
}
-void DocumentTimeline::serviceAnimations(AnimationPlayer::UpdateReason reason)
+void DocumentTimeline::serviceAnimations(TimingUpdateReason reason)
{
TRACE_EVENT0("webkit", "DocumentTimeline::serviceAnimations");
m_timing->cancelWake();
- m_hasOutdatedAnimationPlayer = false;
double timeToNextEffect = std::numeric_limits<double>::infinity();
Vector<AnimationPlayer*> players;
@@ -119,7 +118,7 @@
else if (timeToNextEffect != std::numeric_limits<double>::infinity())
m_timing->wakeAfter(timeToNextEffect - s_minimumDelay);
- ASSERT(!m_hasOutdatedAnimationPlayer);
+ ASSERT(!hasOutdatedAnimationPlayer());
}
void DocumentTimeline::setZeroTime(double zeroTime)
@@ -127,7 +126,7 @@
ASSERT(isNull(m_zeroTime));
m_zeroTime = zeroTime;
ASSERT(!isNull(m_zeroTime));
- serviceAnimations(AnimationPlayer::UpdateOnDemand);
+ serviceAnimations(TimingUpdateOnDemand);
}
void DocumentTimeline::DocumentTimelineTiming::wakeAfter(double duration)
@@ -183,13 +182,22 @@
{
for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
(*it)->pauseForTesting(pauseTime);
- serviceAnimations(AnimationPlayer::UpdateOnDemand);
+ serviceAnimations(TimingUpdateOnDemand);
+}
+
+bool DocumentTimeline::hasOutdatedAnimationPlayer() const
+{
+ for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it) {
+ if ((*it)->outdated())
+ return true;
+ }
+ return false;
}
void DocumentTimeline::setOutdatedAnimationPlayer(AnimationPlayer* player)
{
+ ASSERT(player->outdated());
m_playersNeedingUpdate.add(player);
- m_hasOutdatedAnimationPlayer = true;
if (m_document && m_document->page() && !m_document->page()->animator().isServicingAnimations())
m_timing->serviceOnNextFrame();
}
diff --git a/Source/core/animation/DocumentTimeline.h b/Source/core/animation/DocumentTimeline.h
index 6ff8bdf..a151a30 100644
--- a/Source/core/animation/DocumentTimeline.h
+++ b/Source/core/animation/DocumentTimeline.h
@@ -62,7 +62,7 @@
static PassRefPtr<DocumentTimeline> create(Document*, PassOwnPtr<PlatformTiming> = nullptr);
~DocumentTimeline();
- void serviceAnimations(AnimationPlayer::UpdateReason);
+ void serviceAnimations(TimingUpdateReason);
// Creates a player attached to this timeline, but without a start time.
AnimationPlayer* createAnimationPlayer(TimedItem*);
@@ -89,10 +89,11 @@
size_t numberOfActiveAnimationsForTesting() const;
void setOutdatedAnimationPlayer(AnimationPlayer*);
- bool hasOutdatedAnimationPlayer() const { return m_hasOutdatedAnimationPlayer; }
+ bool hasOutdatedAnimationPlayer() const;
Document* document() { return m_document; }
void detachFromDocument();
+ void wake();
protected:
DocumentTimeline(Document*, PassOwnPtr<PlatformTiming>);
@@ -104,9 +105,6 @@
// i.e. current, in effect, or had timing changed
HashSet<RefPtr<AnimationPlayer> > m_playersNeedingUpdate;
HashSet<AnimationPlayer*> m_players;
- bool m_hasOutdatedAnimationPlayer;
-
- void wake();
friend class SMILTimeContainer;
static const double s_minimumDelay;
diff --git a/Source/core/animation/DocumentTimelineTest.cpp b/Source/core/animation/DocumentTimelineTest.cpp
index aa7981b..8da102b 100644
--- a/Source/core/animation/DocumentTimelineTest.cpp
+++ b/Source/core/animation/DocumentTimelineTest.cpp
@@ -102,7 +102,7 @@
void updateClockAndService(double time)
{
document->animationClock().updateTime(time);
- timeline->serviceAnimations(AnimationPlayer::UpdateForAnimationFrame);
+ timeline->serviceAnimations(TimingUpdateForAnimationFrame);
}
RefPtr<Document> document;
diff --git a/Source/core/animation/InertAnimation.cpp b/Source/core/animation/InertAnimation.cpp
index 4f4ee13..42479bf 100644
--- a/Source/core/animation/InertAnimation.cpp
+++ b/Source/core/animation/InertAnimation.cpp
@@ -48,7 +48,7 @@
PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > InertAnimation::sample(double inheritedTime)
{
- updateInheritedTime(inheritedTime);
+ updateInheritedTime(inheritedTime, TimingUpdateOnDemand);
if (!isInEffect())
return nullptr;
diff --git a/Source/core/animation/InterpolableValue.cpp b/Source/core/animation/InterpolableValue.cpp
index 97dd774..e1b43a9 100644
--- a/Source/core/animation/InterpolableValue.cpp
+++ b/Source/core/animation/InterpolableValue.cpp
@@ -53,6 +53,7 @@
#if ENABLE_OILPAN
visitor->trace(m_values);
#endif
+ InterpolableValue::trace(visitor);
}
PassOwnPtrWillBeRawPtr<InterpolableValue> InterpolableAnimatableValue::interpolate(const InterpolableValue &other, const double percentage) const
@@ -68,6 +69,7 @@
void InterpolableAnimatableValue::trace(Visitor* visitor)
{
visitor->trace(m_value);
+ InterpolableValue::trace(visitor);
}
}
diff --git a/Source/core/animation/InterpolableValue.h b/Source/core/animation/InterpolableValue.h
index 32df14f..3b763aa 100644
--- a/Source/core/animation/InterpolableValue.h
+++ b/Source/core/animation/InterpolableValue.h
@@ -22,7 +22,7 @@
virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const = 0;
- virtual void trace(Visitor*) = 0;
+ virtual void trace(Visitor*) { }
private:
virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const = 0;
@@ -47,7 +47,7 @@
double value() const { return m_value; }
virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { InterpolableValue::trace(visitor); }
private:
virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
@@ -71,7 +71,7 @@
bool value() const { return m_value; }
virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
- virtual void trace(Visitor*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { InterpolableValue::trace(visitor); }
private:
virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
diff --git a/Source/core/animation/Interpolation.cpp b/Source/core/animation/Interpolation.cpp
index 52fdd8d..1738b81 100644
--- a/Source/core/animation/Interpolation.cpp
+++ b/Source/core/animation/Interpolation.cpp
@@ -5,8 +5,7 @@
#include "config.h"
#include "core/animation/Interpolation.h"
-#include "core/animation/AnimatableDouble.h"
-#include "core/animation/AnimatableLength.h"
+#include "core/css/CSSCalculationValue.h"
#include "core/css/resolver/AnimatedStyleBuilder.h"
#include "core/css/resolver/StyleBuilder.h"
#include "core/css/resolver/StyleResolverState.h"
@@ -81,6 +80,20 @@
StyleInterpolation::trace(visitor);
}
+bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value)
+{
+ if (value.isPrimitiveValue()) {
+ const CSSPrimitiveValue& primitiveValue = WebCore::toCSSPrimitiveValue(value);
+ if (primitiveValue.cssCalcValue())
+ return true;
+
+ CSSPrimitiveValue::LengthUnitType type;
+ // Only returns true if the type is a primitive length unit.
+ return CSSPrimitiveValue::unitTypeToLengthUnitType(primitiveValue.primitiveType(), type);
+ }
+ return value.isCalcValue();
+}
+
PassOwnPtrWillBeRawPtr<InterpolableValue> LengthStyleInterpolation::lengthToInterpolableValue(CSSValue* value)
{
OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(CSSPrimitiveValue::LengthUnitTypeCount);
@@ -159,4 +172,16 @@
StyleInterpolation::trace(visitor);
}
+void DefaultStyleInterpolation::apply(StyleResolverState& state) const
+{
+ StyleBuilder::applyProperty(m_id, state, toInterpolableBool(m_cachedValue.get())->value() ? m_endCSSValue.get() : m_startCSSValue.get());
+}
+
+void DefaultStyleInterpolation::trace(Visitor* visitor)
+{
+ StyleInterpolation::trace(visitor);
+ visitor->trace(m_startCSSValue);
+ visitor->trace(m_endCSSValue);
+}
+
}
diff --git a/Source/core/animation/Interpolation.h b/Source/core/animation/Interpolation.h
index 254df7f..206310c 100644
--- a/Source/core/animation/Interpolation.h
+++ b/Source/core/animation/Interpolation.h
@@ -104,6 +104,8 @@
return adoptRefWillBeNoop(new LengthStyleInterpolation(lengthToInterpolableValue(start), lengthToInterpolableValue(end), id));
}
+ static bool canCreateFrom(const CSSValue&);
+
virtual void apply(StyleResolverState&) const OVERRIDE;
virtual void trace(Visitor*) OVERRIDE;
@@ -119,6 +121,27 @@
friend class AnimationInterpolationTest;
};
+class DefaultStyleInterpolation : public StyleInterpolation {
+public:
+ static PassRefPtrWillBeRawPtr<DefaultStyleInterpolation> create(CSSValue* start, CSSValue* end, CSSPropertyID id)
+ {
+ return adoptRefWillBeNoop(new DefaultStyleInterpolation(start, end, id));
+ }
+ virtual void apply(StyleResolverState&) const;
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ DefaultStyleInterpolation(CSSValue* start, CSSValue* end, CSSPropertyID id)
+ : StyleInterpolation(InterpolableBool::create(false), InterpolableBool::create(true), id)
+ , m_startCSSValue(start)
+ , m_endCSSValue(end)
+ {
+ }
+
+ RefPtrWillBeMember<CSSValue> m_startCSSValue;
+ RefPtrWillBeMember<CSSValue> m_endCSSValue;
+};
+
DEFINE_TYPE_CASTS(StyleInterpolation, Interpolation, value, value->isStyleInterpolation(), value.isStyleInterpolation());
DEFINE_TYPE_CASTS(LegacyStyleInterpolation, Interpolation, value, value->isLegacyStyleInterpolation(), value.isLegacyStyleInterpolation());
diff --git a/Source/core/animation/Keyframe.h b/Source/core/animation/Keyframe.h
index 2e0f933..fa3f70a 100644
--- a/Source/core/animation/Keyframe.h
+++ b/Source/core/animation/Keyframe.h
@@ -66,7 +66,7 @@
virtual PassOwnPtrWillBeRawPtr<PropertySpecificKeyframe> neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const = 0;
virtual PassRefPtrWillBeRawPtr<Interpolation> createInterpolation(CSSPropertyID, WebCore::Keyframe::PropertySpecificKeyframe* end, Element*) const = 0;
- virtual void trace(Visitor*) = 0;
+ virtual void trace(Visitor*) { }
protected:
PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, AnimationEffect::CompositeOperation);
diff --git a/Source/core/animation/KeyframeEffectModel.cpp b/Source/core/animation/KeyframeEffectModel.cpp
index c1d0d888..580f621 100644
--- a/Source/core/animation/KeyframeEffectModel.cpp
+++ b/Source/core/animation/KeyframeEffectModel.cpp
@@ -201,6 +201,7 @@
#if ENABLE_OILPAN
visitor->trace(m_keyframeGroups);
#endif
+ AnimationEffect::trace(visitor);
}
Keyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, AnimationEffect::CompositeOperation composite)
diff --git a/Source/core/animation/KeyframeEffectModelTest.cpp b/Source/core/animation/KeyframeEffectModelTest.cpp
index 7a1a364..02bec9c 100644
--- a/Source/core/animation/KeyframeEffectModelTest.cpp
+++ b/Source/core/animation/KeyframeEffectModelTest.cpp
@@ -51,7 +51,7 @@
PassRefPtrWillBeRawPtr<AnimatableValue> pixelAnimatableValue(double n)
{
- return AnimatableLength::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_PX).get());
+ return AnimatableLength::create(Length(n, Fixed), 1);
}
AnimatableValueKeyframeVector keyframesAtZeroAndOne(PassRefPtrWillBeRawPtr<AnimatableValue> zeroValue, PassRefPtrWillBeRawPtr<AnimatableValue> oneValue)
@@ -81,7 +81,7 @@
double actualValue;
if (value->isLength())
- actualValue = toCSSPrimitiveValue(toAnimatableLength(value.get())->toCSSValue().get())->getDoubleValue();
+ actualValue = toAnimatableLength(value.get())->length(1, ValueRangeAll).value();
else
actualValue = toCSSPrimitiveValue(toAnimatableUnknown(value.get())->toCSSValue().get())->getDoubleValue();
diff --git a/Source/core/animation/StringKeyframe.cpp b/Source/core/animation/StringKeyframe.cpp
index 895e19d..c712425 100644
--- a/Source/core/animation/StringKeyframe.cpp
+++ b/Source/core/animation/StringKeyframe.cpp
@@ -5,7 +5,6 @@
#include "config.h"
#include "core/animation/StringKeyframe.h"
-#include "core/animation/AnimatableLength.h"
#include "core/animation/Interpolation.h"
#include "core/animation/css/CSSAnimations.h"
#include "core/css/resolver/StyleResolver.h"
@@ -22,7 +21,8 @@
void StringKeyframe::setPropertyValue(CSSPropertyID property, const String& value, StyleSheetContents* styleSheetContents)
{
ASSERT(property != CSSPropertyInvalid);
- m_propertySet->setProperty(property, value, false, styleSheetContents);
+ if (CSSAnimations::isAllowedAnimation(property))
+ m_propertySet->setProperty(property, value, false, styleSheetContents);
}
PropertySet StringKeyframe::properties() const
@@ -30,12 +30,8 @@
// This is not used in time-critical code, so we probably don't need to
// worry about caching this result.
PropertySet properties;
- for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i) {
- // FIXME: Allow for non-animatable properties.
- CSSPropertyID property = m_propertySet->propertyAt(i).id();
- if (CSSAnimations::isAnimatableProperty(property))
- properties.add(property);
- }
+ for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i)
+ properties.add(m_propertySet->propertyAt(i).id());
return properties;
}
@@ -71,12 +67,15 @@
CSSValue* fromCSSValue = m_value.get();
CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end)->value();
+ if (!CSSAnimations::isAnimatableProperty(property))
+ return DefaultStyleInterpolation::create(fromCSSValue, toCSSValue, property);
+
switch (property) {
case CSSPropertyLeft:
case CSSPropertyRight:
case CSSPropertyWidth:
case CSSPropertyHeight:
- if (AnimatableLength::canCreateFrom(fromCSSValue) && AnimatableLength::canCreateFrom(toCSSValue))
+ if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue))
return LengthStyleInterpolation::create(fromCSSValue, toCSSValue, property);
break;
default:
@@ -110,6 +109,7 @@
{
visitor->trace(m_value);
visitor->trace(m_animatableValueCache);
+ Keyframe::PropertySpecificKeyframe::trace(visitor);
}
}
diff --git a/Source/core/animation/TimedItem.cpp b/Source/core/animation/TimedItem.cpp
index 5002823..9743143 100644
--- a/Source/core/animation/TimedItem.cpp
+++ b/Source/core/animation/TimedItem.cpp
@@ -57,7 +57,6 @@
, m_timing(timing)
, m_eventDelegate(eventDelegate)
, m_calculated()
- , m_isFirstSample(true)
, m_needsUpdate(true)
, m_lastUpdateTime(nullValue())
{
@@ -97,15 +96,12 @@
specifiedTimingChanged();
}
-void TimedItem::updateInheritedTime(double inheritedTime) const
+void TimedItem::updateInheritedTime(double inheritedTime, TimingUpdateReason reason) const
{
bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime)));
m_needsUpdate = false;
m_lastUpdateTime = inheritedTime;
- const double previousIteration = m_calculated.currentIteration;
- const Phase previousPhase = m_calculated.phase;
-
const double localTime = inheritedTime - m_startTime;
double timeToNextIteration = std::numeric_limits<double>::infinity();
if (needsUpdate) {
@@ -162,12 +158,9 @@
// Test for events even if timing didn't need an update as the player may have gained a start time.
// FIXME: Refactor so that we can ASSERT(m_player) here, this is currently required to be nullable for testing.
- if (!m_player || m_player->hasStartTime()) {
- // This logic is specific to CSS animation events and assumes that all
- // animations start after the DocumentTimeline has started.
- if (m_eventDelegate && (m_isFirstSample || previousPhase != phase() || (phase() == PhaseActive && previousIteration != m_calculated.currentIteration)))
- m_eventDelegate->onEventCondition(this, m_isFirstSample, previousPhase, previousIteration);
- m_isFirstSample = false;
+ if (reason == TimingUpdateForAnimationFrame && (!m_player || m_player->hasStartTime())) {
+ if (m_eventDelegate)
+ m_eventDelegate->onEventCondition(this);
}
if (needsUpdate) {
@@ -183,7 +176,7 @@
if (!m_player)
return m_calculated;
if (m_player->outdated())
- m_player->update(AnimationPlayer::UpdateOnDemand);
+ m_player->update(TimingUpdateOnDemand);
ASSERT(!m_player->outdated());
return m_calculated;
}
diff --git a/Source/core/animation/TimedItem.h b/Source/core/animation/TimedItem.h
index 69e82a0..6e026dd 100644
--- a/Source/core/animation/TimedItem.h
+++ b/Source/core/animation/TimedItem.h
@@ -42,6 +42,11 @@
class TimedItem;
class TimedItemTiming;
+enum TimingUpdateReason {
+ TimingUpdateOnDemand,
+ TimingUpdateForAnimationFrame
+};
+
static inline bool isNull(double value)
{
return std::isnan(value);
@@ -66,7 +71,7 @@
class EventDelegate {
public:
virtual ~EventDelegate() { };
- virtual void onEventCondition(const TimedItem*, bool isFirstSample, Phase previousPhase, double previousIteration) = 0;
+ virtual void onEventCondition(const TimedItem*) = 0;
};
virtual ~TimedItem() { }
@@ -111,7 +116,7 @@
// When TimedItem receives a new inherited time via updateInheritedTime
// it will (if necessary) recalculate timings and (if necessary) call
// updateChildrenAndEffects.
- void updateInheritedTime(double inheritedTime) const;
+ void updateInheritedTime(double inheritedTime, TimingUpdateReason) const;
void invalidate() const { m_needsUpdate = true; };
bool hasEvents() const { return m_eventDelegate; }
void clearEventDelegate() { m_eventDelegate = nullptr; }
@@ -158,7 +163,6 @@
double timeToForwardsEffectChange;
double timeToReverseEffectChange;
} m_calculated;
- mutable bool m_isFirstSample;
mutable bool m_needsUpdate;
mutable double m_lastUpdateTime;
diff --git a/Source/core/animation/TimedItemTest.cpp b/Source/core/animation/TimedItemTest.cpp
index 2d48ca3..9bcc621 100644
--- a/Source/core/animation/TimedItemTest.cpp
+++ b/Source/core/animation/TimedItemTest.cpp
@@ -39,27 +39,19 @@
class TestTimedItemEventDelegate : public TimedItem::EventDelegate {
public:
- virtual void onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration) OVERRIDE
+ virtual void onEventCondition(const TimedItem* timedItem) OVERRIDE
{
m_eventTriggered = true;
- m_phaseChanged = previousPhase != timedItem->phase();
- m_iterationChanged = previousIteration != timedItem->currentIteration();
}
void reset()
{
m_eventTriggered = false;
- m_phaseChanged = false;
- m_iterationChanged = false;
}
bool eventTriggered() { return m_eventTriggered; }
- bool phaseChanged() { return m_phaseChanged; }
- bool iterationChanged() { return m_iterationChanged; }
private:
bool m_eventTriggered;
- bool m_phaseChanged;
- bool m_iterationChanged;
};
class TestTimedItem : public TimedItem {
@@ -71,8 +63,13 @@
void updateInheritedTime(double time)
{
+ updateInheritedTime(time, TimingUpdateForAnimationFrame);
+ }
+
+ void updateInheritedTime(double time, TimingUpdateReason reason)
+ {
m_eventDelegate->reset();
- TimedItem::updateInheritedTime(time);
+ TimedItem::updateInheritedTime(time, reason);
}
virtual void updateChildrenAndEffects() const OVERRIDE { }
@@ -723,40 +720,18 @@
timing.startDelay = 1;
RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
- // First sample
- timedItem->updateInheritedTime(0.0);
- EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
-
- // Before start
- timedItem->updateInheritedTime(0.5);
+ timedItem->updateInheritedTime(0.0, TimingUpdateOnDemand);
EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
- // First iteration
- timedItem->updateInheritedTime(1.5);
+ timedItem->updateInheritedTime(0.0, TimingUpdateForAnimationFrame);
EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
- EXPECT_TRUE(timedItem->eventDelegate()->phaseChanged());
- EXPECT_TRUE(timedItem->eventDelegate()->iterationChanged());
- timedItem->updateInheritedTime(1.6);
+ timedItem->updateInheritedTime(1.5, TimingUpdateOnDemand);
EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
- // Second iteration
- timedItem->updateInheritedTime(2.5);
+ timedItem->updateInheritedTime(1.5, TimingUpdateForAnimationFrame);
EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
- EXPECT_FALSE(timedItem->eventDelegate()->phaseChanged());
- EXPECT_TRUE(timedItem->eventDelegate()->iterationChanged());
- timedItem->updateInheritedTime(2.6);
- EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
-
- // After end
- timedItem->updateInheritedTime(3.5);
- EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
- EXPECT_TRUE(timedItem->eventDelegate()->phaseChanged());
- EXPECT_FALSE(timedItem->eventDelegate()->iterationChanged());
-
- timedItem->updateInheritedTime(3.6);
- EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
}
TEST(AnimationTimedItemTest, TimeToEffectChange)
diff --git a/Source/core/animation/css/CSSAnimatableValueFactory.cpp b/Source/core/animation/css/CSSAnimatableValueFactory.cpp
index 6151cc5..b9895bb 100644
--- a/Source/core/animation/css/CSSAnimatableValueFactory.cpp
+++ b/Source/core/animation/css/CSSAnimatableValueFactory.cpp
@@ -66,17 +66,9 @@
{
switch (length.type()) {
case Fixed:
- return AnimatableLength::create(adjustFloatForAbsoluteZoom(length.value(), style), CSSPrimitiveValue::UnitTypePixels);
case Percent:
- return AnimatableLength::create(length.value(), CSSPrimitiveValue::UnitTypePercentage);
- case Calculated: {
- const CalculationValue& calc = length.calculationValue();
- if (calc.pixels() && calc.percent())
- return AnimatableLength::create(CSSCalcValue::createExpressionNode(adjustFloatForAbsoluteZoom(calc.pixels(), style), calc.percent()));
- if (calc.percent())
- return createFromLength(Length(calc.percent(), Percent), style);
- return createFromLength(Length(calc.pixels(), Fixed), style);
- }
+ case Calculated:
+ return AnimatableLength::create(length, style.effectiveZoom());
case Auto:
case Intrinsic:
case MinIntrinsic:
diff --git a/Source/core/animation/css/CSSAnimations.cpp b/Source/core/animation/css/CSSAnimations.cpp
index fb33249..f615333 100644
--- a/Source/core/animation/css/CSSAnimations.cpp
+++ b/Source/core/animation/css/CSSAnimations.cpp
@@ -58,20 +58,6 @@
namespace {
-bool isEarlierPhase(TimedItem::Phase target, TimedItem::Phase reference)
-{
- ASSERT(target != TimedItem::PhaseNone);
- ASSERT(reference != TimedItem::PhaseNone);
- return target < reference;
-}
-
-bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference)
-{
- ASSERT(target != TimedItem::PhaseNone);
- ASSERT(reference != TimedItem::PhaseNone);
- return target > reference;
-}
-
CSSPropertyID propertyForAnimation(CSSPropertyID property)
{
switch (property) {
@@ -160,12 +146,14 @@
if (startKeyframe->offset()) {
startKeyframe = AnimatableValueKeyframe::create();
startKeyframe->setOffset(0);
+ startKeyframe->setEasing(defaultTimingFunction);
keyframes.prepend(startKeyframe);
}
RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = keyframes[keyframes.size() - 1];
if (endKeyframe->offset() != 1) {
endKeyframe = AnimatableValueKeyframe::create();
endKeyframe->setOffset(1);
+ endKeyframe->setEasing(defaultTimingFunction);
keyframes.append(endKeyframe);
}
ASSERT(keyframes.size() >= 2);
@@ -378,7 +366,9 @@
DisableCompositingQueryAsserts disabler;
for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) {
- m_animations.take(*iter)->cancel();
+ RefPtr<AnimationPlayer> player = m_animations.take(*iter);
+ player->cancel();
+ player->update(TimingUpdateOnDemand);
}
for (Vector<AtomicString>::const_iterator iter = update->animationsWithPauseToggled().begin(); iter != update->animationsWithPauseToggled().end(); ++iter) {
@@ -387,6 +377,8 @@
player->unpause();
else
player->pause();
+ if (player->outdated())
+ player->update(TimingUpdateOnDemand);
}
for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
@@ -397,7 +389,7 @@
element->document().compositorPendingAnimations().add(player.get());
if (inertAnimation->paused())
player->pause();
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
m_animations.set(iter->name, player.get());
}
@@ -416,6 +408,7 @@
if (animation->hasActiveAnimationsOnCompositor(id) && update->newTransitions().find(id) != update->newTransitions().end())
retargetedCompositorTransitions.add(id, std::pair<RefPtr<Animation>, double>(animation, player->startTimeInternal()));
player->cancel();
+ player->update(TimingUpdateOnDemand);
}
for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter) {
@@ -456,7 +449,7 @@
RefPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.release());
RefPtr<AnimationPlayer> player = element->document().transitionTimeline().createAnimationPlayer(transition.get());
element->document().compositorPendingAnimations().add(player.get());
- player->update(AnimationPlayer::UpdateOnDemand);
+ player->update(TimingUpdateOnDemand);
runningTransition.player = player;
m_transitions.set(id, runningTransition);
ASSERT(id != CSSPropertyInvalid);
@@ -577,11 +570,11 @@
if (activeTransitions) {
for (TransitionMap::const_iterator iter = activeTransitions->begin(); iter != activeTransitions->end(); ++iter) {
- const TimedItem* timedItem = iter->value.player->source();
+ const AnimationPlayer& player = *iter->value.player;
CSSPropertyID id = iter->key;
- if (timedItem->phase() == TimedItem::PhaseAfter || (!anyTransitionHadAnimateAll && !animationStyleRecalc && !listedProperties.get(id))) {
+ if (player.finishedInternal() || (!anyTransitionHadAnimateAll && !animationStyleRecalc && !listedProperties.get(id))) {
// TODO: Figure out why this fails on Chrome OS login page. crbug.com/365507
- // ASSERT(timedItem->phase() == TimedItem::PhaseAfter || !(activeAnimations && activeAnimations->isAnimationStyleChange()));
+ // ASSERT(player.finishedInternal() || !(activeAnimations && activeAnimations->isAnimationStyleChange()));
update->cancelTransition(id);
}
}
@@ -590,11 +583,15 @@
void CSSAnimations::cancel()
{
- for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter)
+ for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter) {
iter->value->cancel();
+ iter->value->update(TimingUpdateOnDemand);
+ }
- for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transitions.end(); ++iter)
+ for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transitions.end(); ++iter) {
iter->value.player->cancel();
+ iter->value.player->update(TimingUpdateOnDemand);
+ }
m_animations.clear();
m_transitions.clear();
@@ -663,39 +660,41 @@
}
}
-void CSSAnimations::AnimationEventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
+void CSSAnimations::AnimationEventDelegate::onEventCondition(const TimedItem* timedItem)
{
const TimedItem::Phase currentPhase = timedItem->phase();
const double currentIteration = timedItem->currentIteration();
- // Note that the elapsedTime is measured from when the animation starts playing.
- if (!isFirstSample && previousPhase == TimedItem::PhaseActive && currentPhase == TimedItem::PhaseActive && previousIteration != currentIteration) {
- ASSERT(!isNull(previousIteration));
- ASSERT(!isNull(currentIteration));
- // We fire only a single event for all iterations thast terminate
- // between a single pair of samples. See http://crbug.com/275263. For
- // compatibility with the existing implementation, this event uses
- // the elapsedTime for the first iteration in question.
- ASSERT(!std::isnan(timedItem->specifiedTiming().iterationDuration));
- const double elapsedTime = timedItem->specifiedTiming().iterationDuration * (previousIteration + 1);
- maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::animationiteration, elapsedTime);
- return;
- }
- if ((isFirstSample || previousPhase == TimedItem::PhaseBefore) && isLaterPhase(currentPhase, TimedItem::PhaseBefore)) {
- ASSERT(timedItem->specifiedTiming().startDelay > 0 || isFirstSample);
+ if (m_previousPhase != currentPhase
+ && (currentPhase == TimedItem::PhaseActive || currentPhase == TimedItem::PhaseAfter)
+ && (m_previousPhase == TimedItem::PhaseNone || m_previousPhase == TimedItem::PhaseBefore)) {
// The spec states that the elapsed time should be
// 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
// implementation. See crbug.com/279611
maybeDispatch(Document::ANIMATIONSTART_LISTENER, EventTypeNames::animationstart, 0);
}
- if ((isFirstSample || isEarlierPhase(previousPhase, TimedItem::PhaseAfter)) && currentPhase == TimedItem::PhaseAfter)
+
+ if (currentPhase == TimedItem::PhaseActive && m_previousPhase == currentPhase && m_previousIteration != currentIteration) {
+ // We fire only a single event for all iterations thast terminate
+ // between a single pair of samples. See http://crbug.com/275263. For
+ // compatibility with the existing implementation, this event uses
+ // the elapsedTime for the first iteration in question.
+ ASSERT(!std::isnan(timedItem->specifiedTiming().iterationDuration));
+ const double elapsedTime = timedItem->specifiedTiming().iterationDuration * (m_previousIteration + 1);
+ maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::animationiteration, elapsedTime);
+ }
+
+ if (currentPhase == TimedItem::PhaseAfter && m_previousPhase != TimedItem::PhaseAfter)
maybeDispatch(Document::ANIMATIONEND_LISTENER, EventTypeNames::animationend, timedItem->activeDurationInternal());
+
+ m_previousPhase = currentPhase;
+ m_previousIteration = currentIteration;
}
-void CSSAnimations::TransitionEventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
+void CSSAnimations::TransitionEventDelegate::onEventCondition(const TimedItem* timedItem)
{
const TimedItem::Phase currentPhase = timedItem->phase();
- if (currentPhase == TimedItem::PhaseAfter && (isFirstSample || previousPhase != currentPhase) && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
+ if (currentPhase == TimedItem::PhaseAfter && currentPhase != m_previousPhase && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
String propertyName = getPropertyNameString(m_property);
const Timing& timing = timedItem->specifiedTiming();
double elapsedTime = timing.iterationDuration;
@@ -705,6 +704,8 @@
event->setTarget(m_target);
m_target->document().enqueueAnimationFrameEvent(event);
}
+
+ m_previousPhase = currentPhase;
}
bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
@@ -843,6 +844,46 @@
return propertyShorthand;
}
+// Animation properties are not allowed to be affected by Web Animations.
+// http://dev.w3.org/fxtf/web-animations/#not-animatable
+bool CSSAnimations::isAllowedAnimation(CSSPropertyID property)
+{
+ switch (property) {
+ case CSSPropertyAnimation:
+ case CSSPropertyAnimationDelay:
+ case CSSPropertyAnimationDirection:
+ case CSSPropertyAnimationDuration:
+ case CSSPropertyAnimationFillMode:
+ case CSSPropertyAnimationIterationCount:
+ case CSSPropertyAnimationName:
+ case CSSPropertyAnimationPlayState:
+ case CSSPropertyAnimationTimingFunction:
+ case CSSPropertyDisplay:
+ case CSSPropertyTransition:
+ case CSSPropertyTransitionDelay:
+ case CSSPropertyTransitionDuration:
+ case CSSPropertyTransitionProperty:
+ case CSSPropertyTransitionTimingFunction:
+ case CSSPropertyWebkitAnimation:
+ case CSSPropertyWebkitAnimationDelay:
+ case CSSPropertyWebkitAnimationDirection:
+ case CSSPropertyWebkitAnimationDuration:
+ case CSSPropertyWebkitAnimationFillMode:
+ case CSSPropertyWebkitAnimationIterationCount:
+ case CSSPropertyWebkitAnimationName:
+ case CSSPropertyWebkitAnimationPlayState:
+ case CSSPropertyWebkitAnimationTimingFunction:
+ case CSSPropertyWebkitTransition:
+ case CSSPropertyWebkitTransitionDelay:
+ case CSSPropertyWebkitTransitionDuration:
+ case CSSPropertyWebkitTransitionProperty:
+ case CSSPropertyWebkitTransitionTimingFunction:
+ return false;
+ default:
+ return true;
+ }
+}
+
void CSSAnimations::trace(Visitor* visitor)
{
visitor->trace(m_transitions);
diff --git a/Source/core/animation/css/CSSAnimations.h b/Source/core/animation/css/CSSAnimations.h
index 11bb1a6..2f36dfb 100644
--- a/Source/core/animation/css/CSSAnimations.h
+++ b/Source/core/animation/css/CSSAnimations.h
@@ -163,6 +163,7 @@
static bool isAnimatableProperty(CSSPropertyID);
static const StylePropertyShorthand& animatableProperties();
+ static bool isAllowedAnimation(CSSPropertyID);
// FIXME: This should take a const ScopedStyleTree instead of a StyleResolver.
// We should also change the Element* to a const Element*
static PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> calculateUpdate(Element*, const Element& parentElement, const RenderStyle&, RenderStyle* parentStyle, StyleResolver*);
@@ -211,13 +212,17 @@
AnimationEventDelegate(Element* target, const AtomicString& name)
: m_target(target)
, m_name(name)
+ , m_previousPhase(TimedItem::PhaseNone)
+ , m_previousIteration(nullValue())
{
}
- virtual void onEventCondition(const TimedItem*, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration) OVERRIDE;
+ virtual void onEventCondition(const TimedItem*) OVERRIDE;
private:
void maybeDispatch(Document::ListenerType, const AtomicString& eventName, double elapsedTime);
Element* m_target;
const AtomicString m_name;
+ TimedItem::Phase m_previousPhase;
+ double m_previousIteration;
};
class TransitionEventDelegate FINAL : public TimedItem::EventDelegate {
@@ -225,12 +230,14 @@
TransitionEventDelegate(Element* target, CSSPropertyID property)
: m_target(target)
, m_property(property)
+ , m_previousPhase(TimedItem::PhaseNone)
{
}
- virtual void onEventCondition(const TimedItem*, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration) OVERRIDE;
+ virtual void onEventCondition(const TimedItem*) OVERRIDE;
private:
Element* m_target;
const CSSPropertyID m_property;
+ TimedItem::Phase m_previousPhase;
};
};
diff --git a/Source/core/animation/css/CSSPropertyEquality.cpp b/Source/core/animation/css/CSSPropertyEquality.cpp
index b4c8dd7..c879652 100644
--- a/Source/core/animation/css/CSSPropertyEquality.cpp
+++ b/Source/core/animation/css/CSSPropertyEquality.cpp
@@ -6,6 +6,7 @@
#include "core/animation/css/CSSPropertyEquality.h"
#include "core/animation/css/CSSAnimations.h"
+#include "core/rendering/style/DataEquivalency.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/ShadowList.h"
@@ -39,7 +40,7 @@
return false;
break;
case CSSPropertyBackgroundImage:
- if (!StyleImage::imagesEquivalent(aLayer->image(), bLayer->image()))
+ if (!dataEquivalent(aLayer->image(), bLayer->image()))
return false;
break;
default:
@@ -55,12 +56,6 @@
return true;
}
-template <typename T>
-bool ptrsOrValuesEqual(T a, T b)
-{
- return a == b || (a && b && *a == *b);
-}
-
}
bool CSSPropertyEquality::propertiesEqual(CSSPropertyID prop, const RenderStyle& a, const RenderStyle& b)
@@ -78,7 +73,7 @@
case CSSPropertyBackgroundSize:
return fillLayersEqual<CSSPropertyBackgroundSize>(a.backgroundLayers(), b.backgroundLayers());
case CSSPropertyBaselineShift:
- return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.baselineShiftValue(), b.baselineShiftValue());
+ return dataEquivalent(a.baselineShiftValue(), b.baselineShiftValue());
case CSSPropertyBorderBottomColor:
return a.borderBottomColor().resolve(a.color()) == b.borderBottomColor().resolve(b.color())
&& a.visitedLinkBorderBottomColor().resolve(a.color()) == b.visitedLinkBorderBottomColor().resolve(b.color());
@@ -93,7 +88,7 @@
case CSSPropertyBorderImageSlice:
return a.borderImageSlices() == b.borderImageSlices();
case CSSPropertyBorderImageSource:
- return ptrsOrValuesEqual<StyleImage*>(a.borderImageSource(), b.borderImageSource());
+ return dataEquivalent(a.borderImageSource(), b.borderImageSource());
case CSSPropertyBorderImageWidth:
return a.borderImageWidth() == b.borderImageWidth();
case CSSPropertyBorderLeftColor:
@@ -118,7 +113,7 @@
case CSSPropertyBottom:
return a.bottom() == b.bottom();
case CSSPropertyBoxShadow:
- return ptrsOrValuesEqual<ShadowList*>(a.boxShadow(), b.boxShadow());
+ return dataEquivalent(a.boxShadow(), b.boxShadow());
case CSSPropertyClip:
return a.clip() == b.clip();
case CSSPropertyColor:
@@ -157,7 +152,7 @@
case CSSPropertyLineHeight:
return a.specifiedLineHeight() == b.specifiedLineHeight();
case CSSPropertyListStyleImage:
- return ptrsOrValuesEqual<StyleImage*>(a.listStyleImage(), b.listStyleImage());
+ return dataEquivalent(a.listStyleImage(), b.listStyleImage());
case CSSPropertyMarginBottom:
return a.marginBottom() == b.marginBottom();
case CSSPropertyMarginLeft:
@@ -202,7 +197,7 @@
case CSSPropertyShapeMargin:
return a.shapeMargin() == b.shapeMargin();
case CSSPropertyShapeOutside:
- return ptrsOrValuesEqual<ShapeValue*>(a.shapeOutside(), b.shapeOutside());
+ return dataEquivalent(a.shapeOutside(), b.shapeOutside());
case CSSPropertyStopColor:
return a.stopColor() == b.stopColor();
case CSSPropertyStopOpacity:
@@ -211,22 +206,22 @@
return a.strokePaintType() == b.strokePaintType()
&& (a.strokePaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || a.strokePaintColor() == b.strokePaintColor());
case CSSPropertyStrokeDasharray:
- return ptrsOrValuesEqual<PassRefPtr<SVGLengthList> >(a.strokeDashArray(), b.strokeDashArray());
+ return dataEquivalent(a.strokeDashArray(), b.strokeDashArray());
case CSSPropertyStrokeDashoffset:
- return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.strokeDashOffset(), b.strokeDashOffset());
+ return dataEquivalent(a.strokeDashOffset(), b.strokeDashOffset());
case CSSPropertyStrokeMiterlimit:
return a.strokeMiterLimit() == b.strokeMiterLimit();
case CSSPropertyStrokeOpacity:
return a.strokeOpacity() == b.strokeOpacity();
case CSSPropertyStrokeWidth:
- return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.strokeWidth(), b.strokeWidth());
+ return dataEquivalent(a.strokeWidth(), b.strokeWidth());
case CSSPropertyTextDecorationColor:
return a.textDecorationColor().resolve(a.color()) == b.textDecorationColor().resolve(b.color())
&& a.visitedLinkTextDecorationColor().resolve(a.color()) == b.visitedLinkTextDecorationColor().resolve(b.color());
case CSSPropertyTextIndent:
return a.textIndent() == b.textIndent();
case CSSPropertyTextShadow:
- return ptrsOrValuesEqual<ShadowList*>(a.textShadow(), b.textShadow());
+ return dataEquivalent(a.textShadow(), b.textShadow());
case CSSPropertyTop:
return a.top() == b.top();
case CSSPropertyVisibility:
@@ -238,9 +233,9 @@
case CSSPropertyWebkitBorderVerticalSpacing:
return a.verticalBorderSpacing() == b.verticalBorderSpacing();
case CSSPropertyWebkitBoxShadow:
- return ptrsOrValuesEqual<ShadowList*>(a.boxShadow(), b.boxShadow());
+ return dataEquivalent(a.boxShadow(), b.boxShadow());
case CSSPropertyWebkitClipPath:
- return ptrsOrValuesEqual<ClipPathOperation*>(a.clipPath(), b.clipPath());
+ return dataEquivalent(a.clipPath(), b.clipPath());
case CSSPropertyWebkitColumnCount:
return a.columnCount() == b.columnCount();
case CSSPropertyWebkitColumnGap:
@@ -259,11 +254,11 @@
case CSSPropertyWebkitMaskBoxImageSlice:
return a.maskBoxImageSlices() == b.maskBoxImageSlices();
case CSSPropertyWebkitMaskBoxImageSource:
- return ptrsOrValuesEqual<StyleImage*>(a.maskBoxImageSource(), b.maskBoxImageSource());
+ return dataEquivalent(a.maskBoxImageSource(), b.maskBoxImageSource());
case CSSPropertyWebkitMaskBoxImageWidth:
return a.maskBoxImageWidth() == b.maskBoxImageWidth();
case CSSPropertyWebkitMaskImage:
- return ptrsOrValuesEqual<StyleImage*>(a.maskImage(), b.maskImage());
+ return dataEquivalent(a.maskImage(), b.maskImage());
case CSSPropertyWebkitMaskPositionX:
return fillLayersEqual<CSSPropertyWebkitMaskPositionX>(a.maskLayers(), b.maskLayers());
case CSSPropertyWebkitMaskPositionY:
diff --git a/Source/core/animation/css/TransitionTimeline.cpp b/Source/core/animation/css/TransitionTimeline.cpp
index 9680f98..0952326 100644
--- a/Source/core/animation/css/TransitionTimeline.cpp
+++ b/Source/core/animation/css/TransitionTimeline.cpp
@@ -45,7 +45,6 @@
: DocumentTimeline(document, timing)
{
setZeroTime(document->animationClock().currentTime());
- document->animationClock().unfreeze();
}
} // namespace WebCore