Index: Source/core/animation/LengthBoxStyleInterpolation.cpp |
diff --git a/Source/core/animation/LengthBoxStyleInterpolation.cpp b/Source/core/animation/LengthBoxStyleInterpolation.cpp |
index 9ff212a14c78ed7047f50d8254ae616eac2637ff..f79317926cded84c20e4df55eadebbb74ee07e09 100644 |
--- a/Source/core/animation/LengthBoxStyleInterpolation.cpp |
+++ b/Source/core/animation/LengthBoxStyleInterpolation.cpp |
@@ -5,66 +5,99 @@ |
#include "config.h" |
#include "core/animation/LengthBoxStyleInterpolation.h" |
-#include "core/css/Rect.h" |
#include "core/css/resolver/StyleBuilder.h" |
namespace blink { |
-bool LengthBoxStyleInterpolation::canCreateFrom(const CSSValue& value) |
+namespace { |
+ |
+bool onlyLengthToAuto(Rect* startRect, Rect* endRect) |
dstockwell
2015/02/13 02:30:35
Not sure what this name means, is there a more des
evemj (not active)
2015/02/13 04:04:00
Done.
|
{ |
- return value.isPrimitiveValue() && toCSSPrimitiveValue(value).isRect(); |
+ return (startRect->left()->isLength() == endRect->left()->isValueID() || endRect->left()->isLength() == startRect->left()->isValueID()) |
+ && (startRect->right()->isLength() == endRect->right()->isValueID() || endRect->right()->isLength() == startRect->right()->isValueID()) |
+ && (startRect->top()->isLength() == endRect->top()->isValueID() || endRect->top()->isLength() == startRect->top()->isValueID()) |
+ && (startRect->bottom()->isLength() == endRect->bottom()->isValueID() || endRect->bottom()->isLength() == startRect->bottom()->isValueID()); |
} |
-PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::lengthBoxtoInterpolableValue(const CSSValue& lengthBox) |
+} // namespace |
+ |
+PassRefPtrWillBeRawPtr<LengthBoxStyleInterpolation> LengthBoxStyleInterpolation::maybeCreateFrom(CSSValue* start, CSSValue* end, CSSPropertyID id) |
+{ |
+ bool startRect = start->isPrimitiveValue() && toCSSPrimitiveValue(start)->isRect(); |
+ bool endRect = end->isPrimitiveValue() && toCSSPrimitiveValue(end)->isRect(); |
+ bool startAuto = start->isPrimitiveValue() && toCSSPrimitiveValue(start)->isValueID() && toCSSPrimitiveValue(start)->getValueID() == CSSValueAuto; |
+ bool endAuto = end->isPrimitiveValue() && toCSSPrimitiveValue(end)->isValueID() && toCSSPrimitiveValue(end)->getValueID() == CSSValueAuto; |
+ |
+ if (startAuto || endAuto) { |
+ return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(InterpolableBool::create(false), InterpolableBool::create(true), id, false, start, end)); |
+ } |
+ if (startRect && endRect) { |
+ Rect* startRectValue = toCSSPrimitiveValue(start)->getRectValue(); |
+ Rect* endRectValue = toCSSPrimitiveValue(end)->getRectValue(); |
+ |
+ if (onlyLengthToAuto(startRectValue, endRectValue)) |
+ return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(InterpolableBool::create(false), InterpolableBool::create(true), id, false, start, end)); |
dstockwell
2015/02/13 02:30:35
Is this different from a default interpolation (re
evemj (not active)
2015/02/13 04:04:00
Moved to using DefaultStyleInterpolation in String
|
+ return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(lengthBoxtoInterpolableValue(*start, *end, false), lengthBoxtoInterpolableValue(*end, *start, true), id, false, start, end)); |
+ } |
+ if (start->isBorderImageSliceValue() && toCSSBorderImageSliceValue(start)->slices() |
dstockwell
2015/02/13 02:30:35
BorderImageSlice doesn't work the same way with 'a
|
+ && end->isBorderImageSliceValue() && toCSSBorderImageSliceValue(end)->slices() |
+ && toCSSBorderImageSliceValue(start)->m_fill == toCSSBorderImageSliceValue(end)->m_fill) |
+ return adoptRefWillBeNoop(new LengthBoxStyleInterpolation(borderImageSlicetoInterpolableValue(*start), borderImageSlicetoInterpolableValue(*end), id, toCSSBorderImageSliceValue(start)->m_fill, start, end)); |
+ return nullptr; |
+} |
+ |
+PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::lengthBoxtoInterpolableValue(const CSSValue& lengthBox, const CSSValue& matchingValue, bool isEndInterpolation) |
{ |
const int numberOfSides = 4; |
OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(numberOfSides); |
Rect* rect = toCSSPrimitiveValue(lengthBox).getRectValue(); |
+ Rect* matchingRect = toCSSPrimitiveValue(matchingValue).getRectValue(); |
CSSPrimitiveValue* side[numberOfSides] = { rect->left(), rect->right(), rect->top(), rect->bottom() }; |
+ CSSPrimitiveValue* matchingSide[numberOfSides] = { matchingRect->left(), matchingRect->right(), matchingRect->top(), matchingRect->bottom() }; |
for (size_t i = 0; i < numberOfSides; i++) { |
- result->set(i, LengthStyleInterpolation::toInterpolableValue(*side[i])); |
+ if (side[i]->isValueID() || matchingSide[i]->isValueID()) { |
+ result->set(i, InterpolableBool::create(isEndInterpolation)); |
+ } else { |
+ ASSERT(LengthStyleInterpolation::canCreateFrom(*side[i])); |
+ result->set(i, LengthStyleInterpolation::toInterpolableValue(*side[i])); |
+ } |
} |
return result.release(); |
} |
-PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueToLengthBox(InterpolableValue* value, InterpolationRange range) |
-{ |
- InterpolableList* lengthBox = toInterpolableList(value); |
- RefPtrWillBeRawPtr<Rect> result = Rect::create(); |
- |
- result->setLeft(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(0), RangeNonNegative)); |
- result->setRight(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(1), RangeNonNegative)); |
- result->setTop(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(2), RangeNonNegative)); |
- result->setBottom(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(3), RangeNonNegative)); |
- |
- return CSSPrimitiveValue::create(result.release()); |
-} |
+namespace { |
-void LengthBoxStyleInterpolation::apply(StyleResolverState& state) const |
+PassRefPtr<CSSPrimitiveValue> findValue(InterpolableList* lengthBox, size_t i, CSSPrimitiveValue* start[], CSSPrimitiveValue* end[]) |
dstockwell
2015/02/13 02:30:35
findValue is a bit vague, is indexedValueToLength
evemj (not active)
2015/02/13 04:04:00
Done.
sof
2015/02/13 08:40:37
Intentionally kept as findValue()? (This helper di
|
{ |
- if (m_id == CSSPropertyWebkitMaskBoxImageSlice) |
- StyleBuilder::applyProperty(m_id, state, interpolableValueToBorderImageSlice(m_cachedValue.get(), m_fill).get()); |
- else |
- StyleBuilder::applyProperty(m_id, state, interpolableValueToLengthBox(m_cachedValue.get()).get()); |
+ if (lengthBox->get(i)->isBool()) { |
+ if (toInterpolableBool(lengthBox->get(i))->value()) |
+ return end[i]; |
+ return start[i]; |
+ } |
+ return LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(i), RangeAll); |
} |
-void LengthBoxStyleInterpolation::trace(Visitor* visitor) |
-{ |
- StyleInterpolation::trace(visitor); |
} |
-bool LengthBoxStyleInterpolation::matchingFill(CSSValue& start, CSSValue& end) |
+PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueToLengthBox(InterpolableValue* value, const CSSValue& originalStart, const CSSValue& originalEnd) |
{ |
- return toCSSBorderImageSliceValue(start).m_fill == toCSSBorderImageSliceValue(end).m_fill; |
-} |
+ InterpolableList* lengthBox = toInterpolableList(value); |
+ Rect* startRect = toCSSPrimitiveValue(originalStart).getRectValue(); |
+ Rect* endRect = toCSSPrimitiveValue(originalEnd).getRectValue(); |
+ CSSPrimitiveValue* startSides[4] = { startRect->left(), startRect->right(), startRect->top(), startRect->bottom() }; |
+ CSSPrimitiveValue* endSides[4] = { endRect->left(), endRect->right(), endRect->top(), endRect->bottom() }; |
+ RefPtrWillBeRawPtr<Rect> result = Rect::create(); |
-bool LengthBoxStyleInterpolation::canCreateFromBorderImageSlice(CSSValue& value) |
-{ |
- return value.isBorderImageSliceValue() && toCSSBorderImageSliceValue(value).slices(); |
+ result->setLeft(findValue(lengthBox, 0, startSides, endSides)); |
+ result->setRight(findValue(lengthBox, 1, startSides, endSides)); |
+ result->setTop(findValue(lengthBox, 2, startSides, endSides)); |
+ result->setBottom(findValue(lengthBox, 3, startSides, endSides)); |
+ |
+ return CSSPrimitiveValue::create(result.release()); |
} |
-PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::borderImageSlicetoInterpolableValue(CSSValue& value) |
+PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::borderImageSlicetoInterpolableValue(const CSSValue& value) |
{ |
const int numberOfSides = 4; |
OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(numberOfSides); |
@@ -77,22 +110,35 @@ PassOwnPtrWillBeRawPtr<InterpolableValue> LengthBoxStyleInterpolation::borderIma |
return result.release(); |
} |
-static inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> toPrimitiveValue(PassRefPtrWillBeRawPtr<CSSValue> value) |
-{ |
- return adoptRefWillBeNoop(toCSSPrimitiveValue(value.leakRef())); |
-} |
- |
PassRefPtrWillBeRawPtr<CSSValue> LengthBoxStyleInterpolation::interpolableValueToBorderImageSlice(InterpolableValue* value, bool fill) |
{ |
InterpolableList* lengthBox = toInterpolableList(value); |
RefPtrWillBeRawPtr<Quad> quad = Quad::create(); |
- quad->setLeft(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(0), RangeNonNegative))); |
- quad->setRight(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(1), RangeNonNegative))); |
- quad->setTop(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(2), RangeNonNegative))); |
- quad->setBottom(toPrimitiveValue(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(3), RangeNonNegative))); |
+ quad->setLeft(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(0), RangeNonNegative)); |
+ quad->setRight(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(1), RangeNonNegative)); |
+ quad->setTop(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(2), RangeNonNegative)); |
+ quad->setBottom(LengthStyleInterpolation::fromInterpolableValue(*lengthBox->get(3), RangeNonNegative)); |
return CSSBorderImageSliceValue::create(CSSPrimitiveValue::create(quad.release()), fill); |
} |
+void LengthBoxStyleInterpolation::apply(StyleResolverState& state) const |
+{ |
+ if (m_id == CSSPropertyWebkitMaskBoxImageSlice || m_id == CSSPropertyBorderImageSlice) { |
+ StyleBuilder::applyProperty(m_id, state, interpolableValueToBorderImageSlice(m_cachedValue.get(), m_fill).get()); |
+ } else if (m_cachedValue.get()->isBool()) { |
+ StyleBuilder::applyProperty(m_id, state, toInterpolableBool(m_cachedValue.get())->value() ? m_endCSSValue.get() : m_startCSSValue.get()); |
+ } else { |
+ StyleBuilder::applyProperty(m_id, state, interpolableValueToLengthBox(m_cachedValue.get(), *m_startCSSValue, *m_endCSSValue).get()); |
+ } |
+} |
+ |
+void LengthBoxStyleInterpolation::trace(Visitor* visitor) |
+{ |
+ StyleInterpolation::trace(visitor); |
+ visitor->trace(m_startCSSValue); |
+ visitor->trace(m_endCSSValue); |
+} |
+ |
} |