| Index: third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
|
| diff --git a/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dd897271643ab830bdb5c9d86e8202b0f1e0c723
|
| --- /dev/null
|
| +++ b/third_party/WebKit/Source/core/animation/CSSVisibilityInterpolationType.cpp
|
| @@ -0,0 +1,177 @@
|
| +// Copyright 2015 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 "core/animation/CSSVisibilityInterpolationType.h"
|
| +
|
| +#include "core/css/CSSPrimitiveValueMappings.h"
|
| +#include "core/css/resolver/StyleResolverState.h"
|
| +
|
| +namespace blink {
|
| +
|
| +class CSSVisibilityNonInterpolableValue : public NonInterpolableValue {
|
| +public:
|
| + ~CSSVisibilityNonInterpolableValue() final { }
|
| +
|
| + static PassRefPtr<CSSVisibilityNonInterpolableValue> create(EVisibility start, EVisibility end)
|
| + {
|
| + return adoptRef(new CSSVisibilityNonInterpolableValue(start, end));
|
| + }
|
| +
|
| + EVisibility visibility() const
|
| + {
|
| + ASSERT(m_isSingle);
|
| + return m_start;
|
| + }
|
| +
|
| + EVisibility visibility(double fraction) const
|
| + {
|
| + if (m_isSingle || fraction <= 0)
|
| + return m_start;
|
| + if (fraction >= 1)
|
| + return m_end;
|
| + if (m_start == VISIBLE || m_end == VISIBLE)
|
| + return VISIBLE;
|
| + return fraction < 0.5 ? m_start : m_end;
|
| + }
|
| +
|
| + DECLARE_NON_INTERPOLABLE_VALUE_TYPE();
|
| +
|
| +private:
|
| + CSSVisibilityNonInterpolableValue(EVisibility start, EVisibility end)
|
| + : m_start(start)
|
| + , m_end(end)
|
| + , m_isSingle(m_start == m_end)
|
| + { }
|
| +
|
| + const EVisibility m_start;
|
| + const EVisibility m_end;
|
| + const bool m_isSingle;
|
| +};
|
| +
|
| +DEFINE_NON_INTERPOLABLE_VALUE_TYPE(CSSVisibilityNonInterpolableValue);
|
| +DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(CSSVisibilityNonInterpolableValue);
|
| +
|
| +class UnderlyingVisibilityChecker : public InterpolationType::ConversionChecker {
|
| +public:
|
| + ~UnderlyingVisibilityChecker() final {}
|
| +
|
| + static PassOwnPtr<UnderlyingVisibilityChecker> create(const InterpolationType& type, EVisibility visibility)
|
| + {
|
| + return adoptPtr(new UnderlyingVisibilityChecker(type, visibility));
|
| + }
|
| +
|
| +private:
|
| + UnderlyingVisibilityChecker(const InterpolationType& type, EVisibility visibility)
|
| + : ConversionChecker(type)
|
| + , m_visibility(visibility)
|
| + { }
|
| +
|
| + bool isValid(const InterpolationEnvironment&, const UnderlyingValue& underlyingValue) const final
|
| + {
|
| + double underlyingFraction = toInterpolableNumber(underlyingValue->interpolableValue()).value();
|
| + EVisibility underlyingVisibility = toCSSVisibilityNonInterpolableValue(underlyingValue->nonInterpolableValue())->visibility(underlyingFraction);
|
| + return m_visibility == underlyingVisibility;
|
| + }
|
| +
|
| + const EVisibility m_visibility;
|
| +};
|
| +
|
| +class ParentVisibilityChecker : public InterpolationType::ConversionChecker {
|
| +public:
|
| + static PassOwnPtr<ParentVisibilityChecker> create(const InterpolationType& type, EVisibility visibility)
|
| + {
|
| + return adoptPtr(new ParentVisibilityChecker(type, visibility));
|
| + }
|
| +
|
| +private:
|
| + ParentVisibilityChecker(const InterpolationType& type, EVisibility visibility)
|
| + : ConversionChecker(type)
|
| + , m_visibility(visibility)
|
| + { }
|
| +
|
| + bool isValid(const InterpolationEnvironment& environment, const UnderlyingValue&) const final
|
| + {
|
| + return m_visibility == environment.state().parentStyle()->visibility();
|
| + }
|
| +
|
| + DEFINE_INLINE_VIRTUAL_TRACE() { ConversionChecker::trace(visitor); }
|
| +
|
| + const double m_visibility;
|
| +};
|
| +
|
| +PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::createVisibilityValue(EVisibility visibility) const
|
| +{
|
| + return InterpolationValue::create(*this, InterpolableNumber::create(0), CSSVisibilityNonInterpolableValue::create(visibility, visibility));
|
| +}
|
| +
|
| +PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertNeutral(const UnderlyingValue& underlyingValue, ConversionCheckers& conversionCheckers) const
|
| +{
|
| + double underlyingFraction = toInterpolableNumber(underlyingValue->interpolableValue()).value();
|
| + EVisibility underlyingVisibility = toCSSVisibilityNonInterpolableValue(underlyingValue->nonInterpolableValue())->visibility(underlyingFraction);
|
| + conversionCheckers.append(UnderlyingVisibilityChecker::create(*this, underlyingVisibility));
|
| + return createVisibilityValue(underlyingVisibility);
|
| +}
|
| +
|
| +PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertInitial() const
|
| +{
|
| + return createVisibilityValue(VISIBLE);
|
| +}
|
| +
|
| +PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertInherit(const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
|
| +{
|
| + if (!state.parentStyle())
|
| + return nullptr;
|
| + EVisibility inheritedVisibility = state.parentStyle()->visibility();
|
| + conversionCheckers.append(ParentVisibilityChecker::create(*this, inheritedVisibility));
|
| + return createVisibilityValue(inheritedVisibility);
|
| +}
|
| +
|
| +PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertValue(const CSSValue& value, const StyleResolverState& state, ConversionCheckers& conversionCheckers) const
|
| +{
|
| + if (!value.isPrimitiveValue())
|
| + return nullptr;
|
| +
|
| + const CSSPrimitiveValue& primitiveValue = toCSSPrimitiveValue(value);
|
| + CSSValueID keyword = primitiveValue.getValueID();
|
| +
|
| + switch (keyword) {
|
| + case CSSValueHidden:
|
| + case CSSValueVisible:
|
| + case CSSValueCollapse:
|
| + return createVisibilityValue(primitiveValue.convertTo<EVisibility>());
|
| + default:
|
| + return nullptr;
|
| + }
|
| +}
|
| +
|
| +PassOwnPtr<InterpolationValue> CSSVisibilityInterpolationType::maybeConvertUnderlyingValue(const InterpolationEnvironment& environment) const
|
| +{
|
| + return createVisibilityValue(environment.state().style()->visibility());
|
| +}
|
| +
|
| +PassOwnPtr<PairwisePrimitiveInterpolation> CSSVisibilityInterpolationType::mergeSingleConversions(InterpolationValue& startValue, InterpolationValue& endValue) const
|
| +{
|
| + return PairwisePrimitiveInterpolation::create(
|
| + *this,
|
| + InterpolableNumber::create(0),
|
| + InterpolableNumber::create(1),
|
| + CSSVisibilityNonInterpolableValue::create(
|
| + toCSSVisibilityNonInterpolableValue(startValue.nonInterpolableValue())->visibility(),
|
| + toCSSVisibilityNonInterpolableValue(endValue.nonInterpolableValue())->visibility()));
|
| +}
|
| +
|
| +void CSSVisibilityInterpolationType::composite(UnderlyingValue& underlyingValue, double underlyingFraction, const InterpolationValue& value) const
|
| +{
|
| + underlyingValue.set(&value);
|
| +}
|
| +
|
| +void CSSVisibilityInterpolationType::apply(const InterpolableValue& interpolableValue, const NonInterpolableValue* nonInterpolableValue, InterpolationEnvironment& environment) const
|
| +{
|
| + // Visibility interpolation has been deferred to application time here due to its non-linear behaviour.
|
| + double fraction = toInterpolableNumber(interpolableValue).value();
|
| + EVisibility visibility = toCSSVisibilityNonInterpolableValue(nonInterpolableValue)->visibility(fraction);
|
| + environment.state().style()->setVisibility(visibility);
|
| +}
|
| +
|
| +} // namespace blink
|
|
|