| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | |
| 3 * | |
| 4 * This library is free software; you can redistribute it and/or | |
| 5 * modify it under the terms of the GNU Library General Public | |
| 6 * License as published by the Free Software Foundation; either | |
| 7 * version 2 of the License, or (at your option) any later version. | |
| 8 * | |
| 9 * This library is distributed in the hope that it will be useful, | |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 * Library General Public License for more details. | |
| 13 * | |
| 14 * You should have received a copy of the GNU Library General Public License | |
| 15 * along with this library; see the file COPYING.LIB. If not, write to | |
| 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
| 17 * Boston, MA 02110-1301, USA. | |
| 18 */ | |
| 19 | |
| 20 #ifndef SVGAnimatedListPropertyTearOff_h | |
| 21 #define SVGAnimatedListPropertyTearOff_h | |
| 22 | |
| 23 #include "core/svg/properties/SVGAnimatedProperty.h" | |
| 24 #include "core/svg/properties/SVGListPropertyTearOff.h" | |
| 25 #include "core/svg/properties/SVGStaticListPropertyTearOff.h" | |
| 26 | |
| 27 namespace WebCore { | |
| 28 | |
| 29 template<typename PropertyType> | |
| 30 class SVGPropertyTearOff; | |
| 31 | |
| 32 template<typename PropertyType> | |
| 33 class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty { | |
| 34 public: | |
| 35 typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; | |
| 36 typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; | |
| 37 typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache; | |
| 38 typedef SVGListProperty<PropertyType> ListProperty; | |
| 39 typedef SVGListPropertyTearOff<PropertyType> ListPropertyTearOff; | |
| 40 typedef PropertyType ContentType; | |
| 41 | |
| 42 virtual ~SVGAnimatedListPropertyTearOff() | |
| 43 { | |
| 44 if (m_baseVal) | |
| 45 static_cast<ListPropertyTearOff*>(m_baseVal.get())->clearAnimatedPro
perty(); | |
| 46 if (m_animVal) | |
| 47 static_cast<ListPropertyTearOff*>(m_animVal.get())->clearAnimatedPro
perty(); | |
| 48 } | |
| 49 | |
| 50 virtual ListProperty* baseVal() | |
| 51 { | |
| 52 if (!m_baseVal) | |
| 53 m_baseVal = ListPropertyTearOff::create(this, BaseValRole, m_values,
m_wrappers); | |
| 54 return static_cast<ListProperty*>(m_baseVal.get()); | |
| 55 } | |
| 56 | |
| 57 virtual ListProperty* animVal() | |
| 58 { | |
| 59 if (!m_animVal) | |
| 60 m_animVal = ListPropertyTearOff::create(this, AnimValRole, m_values,
m_wrappers); | |
| 61 return static_cast<ListProperty*>(m_animVal.get()); | |
| 62 } | |
| 63 | |
| 64 virtual bool isAnimatedListTearOff() const { return true; } | |
| 65 | |
| 66 int findItem(SVGProperty* property) const | |
| 67 { | |
| 68 // This should ever be called for our baseVal, as animVal can't modify t
he list. | |
| 69 // It's safe to cast to ListPropertyTearOff here as all classes inheriti
ng from us supply their own removeItemFromList() method. | |
| 70 typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::Lis
tItemType> ListItemTearOff; | |
| 71 return static_cast<ListPropertyTearOff*>(m_baseVal.get())->findItem(stat
ic_cast<ListItemTearOff*>(property)); | |
| 72 } | |
| 73 | |
| 74 void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers) | |
| 75 { | |
| 76 // This should ever be called for our baseVal, as animVal can't modify t
he list. | |
| 77 // It's safe to cast to ListPropertyTearOff here as all classes inheriti
ng from us supply their own removeItemFromList() method. | |
| 78 static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(i
temIndex, shouldSynchronizeWrappers); | |
| 79 } | |
| 80 | |
| 81 void detachListWrappers(unsigned newListSize) | |
| 82 { | |
| 83 ListProperty::detachListWrappersAndResize(&m_wrappers, newListSize); | |
| 84 } | |
| 85 | |
| 86 PropertyType& currentAnimatedValue() | |
| 87 { | |
| 88 ASSERT(m_isAnimating); | |
| 89 ASSERT(m_animVal); | |
| 90 return static_cast<ListProperty*>(m_animVal.get())->values(); | |
| 91 } | |
| 92 | |
| 93 const PropertyType& currentBaseValue() const | |
| 94 { | |
| 95 return m_values; | |
| 96 } | |
| 97 | |
| 98 void animationStarted(PropertyType* newAnimVal, bool shouldOwnValues = false
) | |
| 99 { | |
| 100 ASSERT(!m_isAnimating); | |
| 101 ASSERT(newAnimVal); | |
| 102 ASSERT(m_values.size() == m_wrappers.size()); | |
| 103 ASSERT(m_animatedWrappers.isEmpty()); | |
| 104 | |
| 105 // Switch to new passed in value type & new wrappers list. The new wrapp
ers list must be created for the new value. | |
| 106 if (!newAnimVal->isEmpty()) | |
| 107 m_animatedWrappers.fill(nullptr, newAnimVal->size()); | |
| 108 | |
| 109 ListProperty* animVal = static_cast<ListProperty*>(this->animVal()); | |
| 110 animVal->setValuesAndWrappers(newAnimVal, &m_animatedWrappers, shouldOwn
Values); | |
| 111 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
| 112 ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); | |
| 113 m_isAnimating = true; | |
| 114 } | |
| 115 | |
| 116 void animationEnded() | |
| 117 { | |
| 118 ASSERT(m_isAnimating); | |
| 119 ASSERT(m_animVal); | |
| 120 ASSERT(contextElement()); | |
| 121 ASSERT(m_values.size() == m_wrappers.size()); | |
| 122 | |
| 123 ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get()); | |
| 124 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
| 125 ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); | |
| 126 | |
| 127 animVal->setValuesAndWrappers(&m_values, &m_wrappers, false); | |
| 128 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
| 129 ASSERT(animVal->wrappers().size() == m_wrappers.size()); | |
| 130 | |
| 131 m_animatedWrappers.clear(); | |
| 132 m_isAnimating = false; | |
| 133 } | |
| 134 | |
| 135 void synchronizeWrappersIfNeeded() | |
| 136 { | |
| 137 // Eventually the wrapper list needs synchronization because any SVGAnim
ateLengthList::calculateAnimatedValue() call may | |
| 138 // mutate the length of our values() list, and thus the wrapper() cache
needs synchronization, to have the same size. | |
| 139 // Also existing wrappers which point directly at elements in the existi
ng SVGLengthList have to be detached (so a copy | |
| 140 // of them is created, so existing animVal variables in JS are kept-aliv
e). If we'd detach them later the underlying | |
| 141 // SVGLengthList was already mutated, and our list item wrapper tear off
s would point nowhere. Assertions would fire. | |
| 142 ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get()); | |
| 143 animVal->detachListWrappers(animVal->values().size()); | |
| 144 | |
| 145 ASSERT(animVal->values().size() == animVal->wrappers().size()); | |
| 146 ASSERT(animVal->wrappers().size() == m_animatedWrappers.size()); | |
| 147 } | |
| 148 | |
| 149 void animValWillChange() | |
| 150 { | |
| 151 ASSERT(m_isAnimating); | |
| 152 ASSERT(m_animVal); | |
| 153 ASSERT(m_values.size() == m_wrappers.size()); | |
| 154 synchronizeWrappersIfNeeded(); | |
| 155 } | |
| 156 | |
| 157 void animValDidChange() | |
| 158 { | |
| 159 ASSERT(m_isAnimating); | |
| 160 ASSERT(m_animVal); | |
| 161 ASSERT(m_values.size() == m_wrappers.size()); | |
| 162 synchronizeWrappersIfNeeded(); | |
| 163 } | |
| 164 | |
| 165 static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGE
lement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType
animatedPropertyType, PropertyType& values) | |
| 166 { | |
| 167 ASSERT(contextElement); | |
| 168 return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(context
Element, attributeName, animatedPropertyType, values)); | |
| 169 } | |
| 170 | |
| 171 protected: | |
| 172 SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedNa
me& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& valu
es) | |
| 173 : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyTyp
e) | |
| 174 , m_values(values) | |
| 175 { | |
| 176 if (!values.isEmpty()) | |
| 177 m_wrappers.fill(nullptr, values.size()); | |
| 178 } | |
| 179 | |
| 180 PropertyType& m_values; | |
| 181 | |
| 182 ListWrapperCache m_wrappers; | |
| 183 ListWrapperCache m_animatedWrappers; | |
| 184 | |
| 185 RefPtr<SVGProperty> m_baseVal; | |
| 186 RefPtr<SVGProperty> m_animVal; | |
| 187 }; | |
| 188 | |
| 189 } | |
| 190 | |
| 191 #endif // SVGAnimatedListPropertyTearOff_h | |
| OLD | NEW |