Index: Source/core/animation/ListStyleInterpolation.h |
diff --git a/Source/core/animation/ListStyleInterpolation.h b/Source/core/animation/ListStyleInterpolation.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f5f351254b7a590bbb9bd8dd9a255359fd85d4c3 |
--- /dev/null |
+++ b/Source/core/animation/ListStyleInterpolation.h |
@@ -0,0 +1,139 @@ |
+// 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. |
+ |
+#ifndef ListStyleInterpolation_h |
+#define ListStyleInterpolation_h |
+ |
+#include "core/animation/StyleInterpolation.h" |
+#include "core/css/CSSPrimitiveValue.h" |
+#include "core/css/CSSValueList.h" |
+#include "core/css/resolver/StyleBuilder.h" |
+ |
+namespace blink { |
+ |
+template<typename T, typename NI> |
dstockwell
2015/01/30 04:24:01
expand T and NI into CamelWords
I have no idea wh
evemj (not active)
2015/02/02 03:56:02
Done.
|
+class ListStyleInterpolationImpl : public StyleInterpolation { |
+public: |
+ static PassRefPtrWillBeRawPtr<ListStyleInterpolationImpl<T, NI>> create(const CSSValue& start, const CSSValue& end, CSSPropertyID id, InterpolationRange range = RangeAll) |
+ { |
+ OwnPtrWillBeRawPtr<WillBeHeapVector<typename T::NonInterpolableType>> startNonInterpolableData = adoptPtrWillBeNoop(new WillBeHeapVector<typename T::NonInterpolableType>()); |
+ OwnPtrWillBeRawPtr<WillBeHeapVector<typename T::NonInterpolableType>> endNonInterpolableData = adoptPtrWillBeNoop(new WillBeHeapVector<typename T::NonInterpolableType>()); |
+ |
+ const CSSValueList& startList = toCSSValueList(start); |
+ const CSSValueList& endList = toCSSValueList(end); |
+ |
+ for (size_t i = 0; i < toCSSValueList(start).length(); i++) { |
+ if (!T::canCreateFrom(*startList.item(i), *endList.item(i))) { |
+ return nullptr; |
+ } |
+ } |
+ |
+ OwnPtrWillBeRawPtr<InterpolableValue> startValue = listToInterpolableValue(start, *startNonInterpolableData.get()); |
+ OwnPtrWillBeRawPtr<InterpolableValue> endValue = listToInterpolableValue(end, *endNonInterpolableData.get()); |
+ |
+ return adoptRefWillBeNoop(new ListStyleInterpolationImpl<T, NI>(startValue.release(), endValue.release(), id, startNonInterpolableData.release(), range)); |
+ } |
+ |
+ virtual void apply(StyleResolverState& state) const override |
+ { |
+ StyleBuilder::applyProperty(m_id, state, interpolableValueToList(m_cachedValue.get(), *m_nonInterpolableData.get(), m_range).get()); |
+ } |
+ |
+private: |
+ ListStyleInterpolationImpl(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end, CSSPropertyID id, |
+ PassOwnPtrWillBeRawPtr<WillBeHeapVector<typename T::NonInterpolableType>> nonInterpolableData, InterpolationRange range = RangeAll) |
+ : StyleInterpolation(start, end, id), m_range(range), m_nonInterpolableData(nonInterpolableData) |
+ { |
+ } |
+ |
+ InterpolationRange m_range; |
+ |
+ OwnPtrWillBeRawPtr<WillBeHeapVector<typename T::NonInterpolableType>> m_nonInterpolableData; |
dstockwell
2015/01/30 04:24:01
Why heap vector?
evemj (not active)
2015/02/02 03:56:02
Done.
I didn't fully understand how the WillBeHea
|
+ |
+ static PassOwnPtrWillBeRawPtr<InterpolableValue> listToInterpolableValue(const CSSValue& value, WillBeHeapVector<typename T::NonInterpolableType>& nonInterpolableData) |
+ { |
+ const CSSValueList& listValue = toCSSValueList(value); |
+ nonInterpolableData.reserveCapacity(listValue.length()); |
+ OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(listValue.length()); |
+ typename T::NonInterpolableType elementData = false; |
dstockwell
2015/01/30 04:24:01
Can't NonInterpolableType be something other than
samli
2015/01/30 07:20:30
Yes. @eve: this shouldn't be here anymore :)
evemj (not active)
2015/02/02 03:56:02
Yep sorry that was a mistake!
Done.
|
+ for (size_t i = 0; i < listValue.length(); i++) { |
+ result->set(i, T::toInterpolableValue(*listValue.item(i), elementData)); |
+ nonInterpolableData.append(elementData); |
+ } |
+ return result.release(); |
+ } |
+ |
+ static PassRefPtrWillBeRawPtr<CSSValue> interpolableValueToList(InterpolableValue* value, const WillBeHeapVector<typename T::NonInterpolableType>& nonInterpolableData, InterpolationRange range = RangeAll) |
+ { |
+ InterpolableList* listValue = toInterpolableList(value); |
+ RefPtrWillBeRawPtr<CSSValueList> result = CSSValueList::createCommaSeparated(); |
+ |
+ ASSERT(nonInterpolableData.size() != 0); |
+ |
+ for (size_t i = 0; i < listValue->length(); i++) |
+ result->append(T::fromInterpolableValue(*(listValue->get(i)), nonInterpolableData[i], range)); |
+ return result.release(); |
+ } |
+ |
+ friend class ListStyleInterpolationTest; |
+}; |
+ |
+template<typename T> |
+class ListStyleInterpolationImpl<T, void> : public StyleInterpolation { |
+public: |
+ static PassRefPtrWillBeRawPtr<ListStyleInterpolationImpl<T, void>> create(const CSSValue& start, const CSSValue& end, CSSPropertyID id, InterpolationRange range = RangeAll) |
+ { |
+ return adoptRefWillBeNoop(new ListStyleInterpolationImpl<T, void>(listToInterpolableValue(start), listToInterpolableValue(end), id, range)); |
+ } |
+ |
+private: |
+ ListStyleInterpolationImpl(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end, CSSPropertyID id, InterpolationRange range = RangeAll) |
+ : StyleInterpolation(start, end, id), m_range(range) |
+ { |
+ } |
+ |
+ InterpolationRange m_range; |
+ |
+ static PassOwnPtrWillBeRawPtr<InterpolableValue> listToInterpolableValue(const CSSValue& value) |
+ { |
+ const CSSValueList& listValue = toCSSValueList(value); |
+ OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(listValue.length()); |
+ for (size_t i = 0; i < listValue.length(); i++) |
+ result->set(i, T::toInterpolableValue(*listValue.item(i))); |
+ return result.release(); |
+ } |
+ |
+ static PassRefPtrWillBeRawPtr<CSSValue> interpolableValueToList(InterpolableValue* value, InterpolationRange range = RangeAll) |
+ { |
+ InterpolableList* listValue = toInterpolableList(value); |
+ RefPtrWillBeRawPtr<CSSValueList> result = CSSValueList::createCommaSeparated(); |
+ |
+ for (size_t i = 0; i < listValue->length(); i++) |
+ result->append(T::fromInterpolableValue(*(listValue->get(i)), range)); |
+ return result.release(); |
+ } |
+ |
+ virtual void apply(StyleResolverState& state) const override |
+ { |
+ StyleBuilder::applyProperty(m_id, state, interpolableValueToList(m_cachedValue.get(), m_range).get()); |
+ } |
+ |
+ friend class ListStyleInterpolationTest; |
+ |
+}; |
+ |
+template<typename T> |
+class ListStyleInterpolation { |
+public: |
+ static PassRefPtrWillBeRawPtr<ListStyleInterpolationImpl<T, typename T::NonInterpolableType>> maybeCreateFromList(const CSSValue& start, const CSSValue& end, CSSPropertyID id, InterpolationRange range = RangeAll) |
+ { |
+ if (start.isValueList() && end.isValueList() && toCSSValueList(start).length() == toCSSValueList(end).length()) |
dstockwell
2015/01/30 04:24:01
Don't we need to support lists of different length
evemj (not active)
2015/02/02 03:56:02
I think this class is just for simple lists (not r
dstockwell
2015/02/02 06:10:11
Will we create a separate template for repeatable
evemj (not active)
2015/02/03 00:25:55
I got the impression that we would extend this tem
|
+ return ListStyleInterpolationImpl<T, typename T::NonInterpolableType>::create(start, end, id, range); |
+ return nullptr; |
+ } |
+}; |
+ |
+} // namespace blink |
+ |
+#endif // ListStyleInterpolation_h |