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

Unified Diff: third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp

Issue 2696563006: Add "auto" handling to border-image-width animations (Closed)
Patch Set: default Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/animations/interpolation/border-image-width-interpolation-expected.txt ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
diff --git a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
index 9625b29a1e364c88aa653b867af7573c5d8a4cbe..f9b781a5b6b9ec28426a4ac8dedbc1aa8cb73b84 100644
--- a/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
+++ b/third_party/WebKit/Source/core/animation/CSSBorderImageLengthBoxInterpolationType.cpp
@@ -4,12 +4,13 @@
#include "core/animation/CSSBorderImageLengthBoxInterpolationType.h"
+#include <memory>
#include "core/animation/BorderImageLengthBoxPropertyFunctions.h"
#include "core/animation/LengthInterpolationFunctions.h"
+#include "core/css/CSSIdentifierValue.h"
#include "core/css/CSSQuadValue.h"
#include "core/css/resolver/StyleResolverState.h"
#include "wtf/PtrUtil.h"
-#include <memory>
namespace blink {
@@ -23,34 +24,58 @@ enum SideIndex : unsigned {
SideIndexCount,
};
-struct SideNumbers {
- explicit SideNumbers(const BorderImageLengthBox& box) {
- isNumber[SideTop] = box.top().isNumber();
- isNumber[SideRight] = box.right().isNumber();
- isNumber[SideBottom] = box.bottom().isNumber();
- isNumber[SideLeft] = box.left().isNumber();
+enum class SideType {
+ Number,
+ Auto,
+ Length,
+};
+
+SideType getSideType(const BorderImageLength& side) {
+ if (side.isNumber()) {
+ return SideType::Number;
+ }
+ if (side.length().isAuto()) {
+ return SideType::Auto;
+ }
+ DCHECK(side.length().isSpecified());
+ return SideType::Length;
+}
+
+SideType getSideType(const CSSValue& side) {
+ if (side.isPrimitiveValue() && toCSSPrimitiveValue(side).isNumber()) {
+ return SideType::Number;
+ }
+ if (side.isIdentifierValue() &&
+ toCSSIdentifierValue(side).getValueID() == CSSValueAuto) {
+ return SideType::Auto;
+ }
+ return SideType::Length;
+}
+
+struct SideTypes {
+ explicit SideTypes(const BorderImageLengthBox& box) {
+ type[SideTop] = getSideType(box.top());
+ type[SideRight] = getSideType(box.right());
+ type[SideBottom] = getSideType(box.bottom());
+ type[SideLeft] = getSideType(box.left());
}
- explicit SideNumbers(const CSSQuadValue& quad) {
- isNumber[SideTop] = quad.top()->isPrimitiveValue() &&
- toCSSPrimitiveValue(quad.top())->isNumber();
- isNumber[SideRight] = quad.right()->isPrimitiveValue() &&
- toCSSPrimitiveValue(quad.right())->isNumber();
- isNumber[SideBottom] = quad.bottom()->isPrimitiveValue() &&
- toCSSPrimitiveValue(quad.bottom())->isNumber();
- isNumber[SideLeft] = quad.left()->isPrimitiveValue() &&
- toCSSPrimitiveValue(quad.left())->isNumber();
+ explicit SideTypes(const CSSQuadValue& quad) {
+ type[SideTop] = getSideType(*quad.top());
+ type[SideRight] = getSideType(*quad.right());
+ type[SideBottom] = getSideType(*quad.bottom());
+ type[SideLeft] = getSideType(*quad.left());
}
- bool operator==(const SideNumbers& other) const {
+ bool operator==(const SideTypes& other) const {
for (size_t i = 0; i < SideIndexCount; i++) {
- if (isNumber[i] != other.isNumber[i])
+ if (type[i] != other.type[i])
return false;
}
return true;
}
- bool operator!=(const SideNumbers& other) const { return !(*this == other); }
+ bool operator!=(const SideTypes& other) const { return !(*this == other); }
- bool isNumber[SideIndexCount];
+ SideType type[SideIndexCount];
};
} // namespace
@@ -59,13 +84,19 @@ class CSSBorderImageLengthBoxNonInterpolableValue
: public NonInterpolableValue {
public:
static PassRefPtr<CSSBorderImageLengthBoxNonInterpolableValue> create(
- const SideNumbers& sideNumbers,
+ const SideTypes& sideTypes,
Vector<RefPtr<NonInterpolableValue>>&& sideNonInterpolableValues) {
return adoptRef(new CSSBorderImageLengthBoxNonInterpolableValue(
- sideNumbers, std::move(sideNonInterpolableValues)));
+ sideTypes, std::move(sideNonInterpolableValues)));
+ }
+
+ PassRefPtr<CSSBorderImageLengthBoxNonInterpolableValue> clone() {
+ return adoptRef(new CSSBorderImageLengthBoxNonInterpolableValue(
+ m_sideTypes,
+ Vector<RefPtr<NonInterpolableValue>>(m_sideNonInterpolableValues)));
}
- const SideNumbers& sideNumbers() const { return m_sideNumbers; }
+ const SideTypes& sideTypes() const { return m_sideTypes; }
const Vector<RefPtr<NonInterpolableValue>>& sideNonInterpolableValues()
const {
return m_sideNonInterpolableValues;
@@ -78,14 +109,14 @@ class CSSBorderImageLengthBoxNonInterpolableValue
private:
CSSBorderImageLengthBoxNonInterpolableValue(
- const SideNumbers& sideNumbers,
+ const SideTypes& sideTypes,
Vector<RefPtr<NonInterpolableValue>>&& sideNonInterpolableValues)
- : m_sideNumbers(sideNumbers),
+ : m_sideTypes(sideTypes),
m_sideNonInterpolableValues(sideNonInterpolableValues) {
DCHECK_EQ(m_sideNonInterpolableValues.size(), SideIndexCount);
}
- const SideNumbers m_sideNumbers;
+ const SideTypes m_sideTypes;
Vector<RefPtr<NonInterpolableValue>> m_sideNonInterpolableValues;
};
@@ -95,59 +126,56 @@ DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS(
namespace {
-class UnderlyingSideNumbersChecker
- : public InterpolationType::ConversionChecker {
+class UnderlyingSideTypesChecker : public InterpolationType::ConversionChecker {
public:
- static std::unique_ptr<UnderlyingSideNumbersChecker> create(
- const SideNumbers& underlyingSideNumbers) {
- return WTF::wrapUnique(
- new UnderlyingSideNumbersChecker(underlyingSideNumbers));
+ static std::unique_ptr<UnderlyingSideTypesChecker> create(
+ const SideTypes& underlyingSideTypes) {
+ return WTF::wrapUnique(new UnderlyingSideTypesChecker(underlyingSideTypes));
}
- static SideNumbers getUnderlyingSideNumbers(
+ static SideTypes getUnderlyingSideTypes(
const InterpolationValue& underlying) {
return toCSSBorderImageLengthBoxNonInterpolableValue(
*underlying.nonInterpolableValue)
- .sideNumbers();
+ .sideTypes();
}
private:
- UnderlyingSideNumbersChecker(const SideNumbers& underlyingSideNumbers)
- : m_underlyingSideNumbers(underlyingSideNumbers) {}
+ UnderlyingSideTypesChecker(const SideTypes& underlyingSideTypes)
+ : m_underlyingSideTypes(underlyingSideTypes) {}
bool isValid(const InterpolationEnvironment&,
const InterpolationValue& underlying) const final {
- return m_underlyingSideNumbers == getUnderlyingSideNumbers(underlying);
+ return m_underlyingSideTypes == getUnderlyingSideTypes(underlying);
}
- const SideNumbers m_underlyingSideNumbers;
+ const SideTypes m_underlyingSideTypes;
};
-class InheritedSideNumbersChecker
- : public InterpolationType::ConversionChecker {
+class InheritedSideTypesChecker : public InterpolationType::ConversionChecker {
public:
- static std::unique_ptr<InheritedSideNumbersChecker> create(
+ static std::unique_ptr<InheritedSideTypesChecker> create(
CSSPropertyID property,
- const SideNumbers& inheritedSideNumbers) {
+ const SideTypes& inheritedSideTypes) {
return WTF::wrapUnique(
- new InheritedSideNumbersChecker(property, inheritedSideNumbers));
+ new InheritedSideTypesChecker(property, inheritedSideTypes));
}
private:
- InheritedSideNumbersChecker(CSSPropertyID property,
- const SideNumbers& inheritedSideNumbers)
- : m_property(property), m_inheritedSideNumbers(inheritedSideNumbers) {}
+ InheritedSideTypesChecker(CSSPropertyID property,
+ const SideTypes& inheritedSideTypes)
+ : m_property(property), m_inheritedSideTypes(inheritedSideTypes) {}
bool isValid(const InterpolationEnvironment& environment,
const InterpolationValue& underlying) const final {
- return m_inheritedSideNumbers ==
- SideNumbers(
+ return m_inheritedSideTypes ==
+ SideTypes(
BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox(
m_property, *environment.state().parentStyle()));
}
const CSSPropertyID m_property;
- const SideNumbers m_inheritedSideNumbers;
+ const SideTypes m_inheritedSideTypes;
};
InterpolationValue convertBorderImageLengthBox(const BorderImageLengthBox& box,
@@ -165,6 +193,8 @@ InterpolationValue convertBorderImageLengthBox(const BorderImageLengthBox& box,
const BorderImageLength& side = *sides[i];
if (side.isNumber()) {
list->set(i, InterpolableNumber::create(side.number()));
+ } else if (side.length().isAuto()) {
+ list->set(i, InterpolableList::create(0));
} else {
InterpolationValue convertedSide =
LengthInterpolationFunctions::maybeConvertLength(side.length(), zoom);
@@ -177,7 +207,7 @@ InterpolationValue convertBorderImageLengthBox(const BorderImageLengthBox& box,
return InterpolationValue(
std::move(list), CSSBorderImageLengthBoxNonInterpolableValue::create(
- SideNumbers(box), std::move(nonInterpolableValues)));
+ SideTypes(box), std::move(nonInterpolableValues)));
}
} // namespace
@@ -186,18 +216,14 @@ InterpolationValue
CSSBorderImageLengthBoxInterpolationType::maybeConvertNeutral(
const InterpolationValue& underlying,
ConversionCheckers& conversionCheckers) const {
- SideNumbers underlyingSideNumbers =
- UnderlyingSideNumbersChecker::getUnderlyingSideNumbers(underlying);
+ SideTypes underlyingSideTypes =
+ UnderlyingSideTypesChecker::getUnderlyingSideTypes(underlying);
conversionCheckers.push_back(
- UnderlyingSideNumbersChecker::create(underlyingSideNumbers));
- const auto& zero = [&underlyingSideNumbers](size_t index) {
- return underlyingSideNumbers.isNumber[index]
- ? BorderImageLength(0)
- : BorderImageLength(Length(0, Fixed));
- };
- BorderImageLengthBox zeroBox(zero(SideTop), zero(SideRight), zero(SideBottom),
- zero(SideLeft));
- return convertBorderImageLengthBox(zeroBox, 1);
+ UnderlyingSideTypesChecker::create(underlyingSideTypes));
+ return InterpolationValue(underlying.interpolableValue->cloneAndZero(),
+ toCSSBorderImageLengthBoxNonInterpolableValue(
+ *underlying.nonInterpolableValue)
+ .clone());
}
InterpolationValue
@@ -217,8 +243,8 @@ CSSBorderImageLengthBoxInterpolationType::maybeConvertInherit(
const BorderImageLengthBox& inherited =
BorderImageLengthBoxPropertyFunctions::getBorderImageLengthBox(
cssProperty(), *state.parentStyle());
- conversionCheckers.push_back(InheritedSideNumbersChecker::create(
- cssProperty(), SideNumbers(inherited)));
+ conversionCheckers.push_back(
+ InheritedSideTypesChecker::create(cssProperty(), SideTypes(inherited)));
return convertBorderImageLengthBox(inherited,
state.parentStyle()->effectiveZoom());
}
@@ -245,6 +271,9 @@ InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertValue(
if (side.isPrimitiveValue() && toCSSPrimitiveValue(side).isNumber()) {
list->set(i, InterpolableNumber::create(
toCSSPrimitiveValue(side).getDoubleValue()));
+ } else if (side.isIdentifierValue() &&
+ toCSSIdentifierValue(side).getValueID() == CSSValueAuto) {
+ list->set(i, InterpolableList::create(0));
} else {
InterpolationValue convertedSide =
LengthInterpolationFunctions::maybeConvertCSSValue(side);
@@ -256,9 +285,8 @@ InterpolationValue CSSBorderImageLengthBoxInterpolationType::maybeConvertValue(
}
return InterpolationValue(
- std::move(list),
- CSSBorderImageLengthBoxNonInterpolableValue::create(
- SideNumbers(quad), std::move(nonInterpolableValues)));
+ std::move(list), CSSBorderImageLengthBoxNonInterpolableValue::create(
+ SideTypes(quad), std::move(nonInterpolableValues)));
}
InterpolationValue CSSBorderImageLengthBoxInterpolationType::
@@ -274,14 +302,13 @@ PairwiseInterpolationValue
CSSBorderImageLengthBoxInterpolationType::maybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
- const SideNumbers& startSideNumbers =
+ const SideTypes& startSideTypes =
toCSSBorderImageLengthBoxNonInterpolableValue(*start.nonInterpolableValue)
- .sideNumbers();
- const SideNumbers& endSideNumbers =
+ .sideTypes();
+ const SideTypes& endSideTypes =
toCSSBorderImageLengthBoxNonInterpolableValue(*end.nonInterpolableValue)
- .sideNumbers();
-
- if (startSideNumbers != endSideNumbers)
+ .sideTypes();
+ if (startSideTypes != endSideTypes)
return nullptr;
return PairwiseInterpolationValue(std::move(start.interpolableValue),
@@ -294,16 +321,16 @@ void CSSBorderImageLengthBoxInterpolationType::composite(
double underlyingFraction,
const InterpolationValue& value,
double interpolationFraction) const {
- const SideNumbers& underlyingSideNumbers =
+ const SideTypes& underlyingSideTypes =
toCSSBorderImageLengthBoxNonInterpolableValue(
*underlyingValueOwner.value().nonInterpolableValue)
- .sideNumbers();
+ .sideTypes();
const auto& nonInterpolableValue =
toCSSBorderImageLengthBoxNonInterpolableValue(
*value.nonInterpolableValue);
- const SideNumbers& sideNumbers = nonInterpolableValue.sideNumbers();
+ const SideTypes& sideTypes = nonInterpolableValue.sideTypes();
- if (underlyingSideNumbers != sideNumbers) {
+ if (underlyingSideTypes != sideTypes) {
underlyingValueOwner.set(*this, value);
return;
}
@@ -320,13 +347,23 @@ void CSSBorderImageLengthBoxInterpolationType::composite(
nonInterpolableValue.sideNonInterpolableValues();
for (size_t i = 0; i < SideIndexCount; i++) {
- if (sideNumbers.isNumber[i])
- underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction,
- *list.get(i));
- else
- LengthInterpolationFunctions::composite(
- underlyingList.getMutable(i), underlyingSideNonInterpolableValues[i],
- underlyingFraction, *list.get(i), sideNonInterpolableValues[i].get());
+ switch (sideTypes.type[i]) {
+ case SideType::Number:
+ underlyingList.getMutable(i)->scaleAndAdd(underlyingFraction,
+ *list.get(i));
+ break;
+ case SideType::Length:
+ LengthInterpolationFunctions::composite(
+ underlyingList.getMutable(i),
+ underlyingSideNonInterpolableValues[i], underlyingFraction,
+ *list.get(i), sideNonInterpolableValues[i].get());
+ break;
+ case SideType::Auto:
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
}
}
@@ -334,21 +371,29 @@ void CSSBorderImageLengthBoxInterpolationType::applyStandardPropertyValue(
const InterpolableValue& interpolableValue,
const NonInterpolableValue* nonInterpolableValue,
StyleResolverState& state) const {
- const SideNumbers& sideNumbers =
+ const SideTypes& sideTypes =
toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue)
- ->sideNumbers();
+ ->sideTypes();
const Vector<RefPtr<NonInterpolableValue>>& nonInterpolableValues =
toCSSBorderImageLengthBoxNonInterpolableValue(nonInterpolableValue)
->sideNonInterpolableValues();
const InterpolableList& list = toInterpolableList(interpolableValue);
- const auto& convertSide =
- [&sideNumbers, &list, &state,
- &nonInterpolableValues](size_t index) -> BorderImageLength {
- if (sideNumbers.isNumber[index])
- return clampTo<double>(toInterpolableNumber(list.get(index))->value(), 0);
- return LengthInterpolationFunctions::createLength(
- *list.get(index), nonInterpolableValues[index].get(),
- state.cssToLengthConversionData(), ValueRangeNonNegative);
+ const auto& convertSide = [&sideTypes, &list, &state, &nonInterpolableValues](
+ size_t index) -> BorderImageLength {
+ switch (sideTypes.type[index]) {
+ case SideType::Number:
+ return clampTo<double>(toInterpolableNumber(list.get(index))->value(),
+ 0);
+ case SideType::Auto:
+ return Length(Auto);
+ case SideType::Length:
+ return LengthInterpolationFunctions::createLength(
+ *list.get(index), nonInterpolableValues[index].get(),
+ state.cssToLengthConversionData(), ValueRangeNonNegative);
+ default:
+ NOTREACHED();
+ return Length(Auto);
+ }
};
BorderImageLengthBox box(convertSide(SideTop), convertSide(SideRight),
convertSide(SideBottom), convertSide(SideLeft));
« no previous file with comments | « third_party/WebKit/LayoutTests/animations/interpolation/border-image-width-interpolation-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698