Home | History | Annotate | Download | only in properties
      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 #if ENABLE(SVG)
     24 #include "SVGAnimatedProperty.h"
     25 #include "SVGListPropertyTearOff.h"
     26 #include "SVGStaticListPropertyTearOff.h"
     27 
     28 namespace WebCore {
     29 
     30 template<typename PropertyType>
     31 class SVGPropertyTearOff;
     32 
     33 template<typename PropertyType>
     34 class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty {
     35 public:
     36     typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
     37     typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
     38     typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache;
     39 
     40     SVGProperty* baseVal()
     41     {
     42         if (!m_baseVal)
     43             m_baseVal = SVGListPropertyTearOff<PropertyType>::create(this, BaseValRole);
     44         return m_baseVal.get();
     45     }
     46 
     47     SVGProperty* animVal()
     48     {
     49         if (!m_animVal)
     50             m_animVal = SVGListPropertyTearOff<PropertyType>::create(this, AnimValRole);
     51         return m_animVal.get();
     52     }
     53 
     54     virtual bool isAnimatedListTearOff() const { return true; }
     55 
     56     int removeItemFromList(SVGProperty* property, bool shouldSynchronizeWrappers)
     57     {
     58         // This should ever be called for our baseVal, as animVal can't modify the list.
     59         typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::ListItemType> ListItemTearOff;
     60         return static_pointer_cast<SVGListPropertyTearOff<PropertyType> >(m_baseVal)->removeItemFromList(static_cast<ListItemTearOff*>(property), shouldSynchronizeWrappers);
     61     }
     62 
     63     void detachListWrappers(unsigned newListSize)
     64     {
     65         // See SVGPropertyTearOff::detachWrapper() for an explaination what's happening here.
     66         unsigned size = m_wrappers.size();
     67         ASSERT(size == m_values.size());
     68         for (unsigned i = 0; i < size; ++i) {
     69             RefPtr<ListItemTearOff>& item = m_wrappers.at(i);
     70             if (!item)
     71                 continue;
     72             item->detachWrapper();
     73         }
     74 
     75         // Reinitialize the wrapper cache to be equal to the new values size, after the XML DOM changed the list.
     76         if (newListSize)
     77             m_wrappers.fill(0, newListSize);
     78         else
     79             m_wrappers.clear();
     80     }
     81 
     82     PropertyType& values() { return m_values; }
     83     ListWrapperCache& wrappers() { return m_wrappers; }
     84 
     85 private:
     86     friend class SVGAnimatedProperty;
     87 
     88     static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& values)
     89     {
     90         ASSERT(contextElement);
     91         return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, values));
     92     }
     93 
     94 protected:
     95     SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, PropertyType& values)
     96         : SVGAnimatedProperty(contextElement, attributeName)
     97         , m_values(values)
     98     {
     99         if (!values.isEmpty())
    100             m_wrappers.fill(0, values.size());
    101     }
    102 
    103     PropertyType& m_values;
    104 
    105     // FIXME: The list wrapper cache is shared between baseVal/animVal. If we implement animVal,
    106     // we need two seperated wrapper caches if the attribute gets animated.
    107     ListWrapperCache m_wrappers;
    108 
    109     RefPtr<SVGProperty> m_baseVal;
    110     RefPtr<SVGProperty> m_animVal;
    111 };
    112 
    113 }
    114 
    115 #endif // ENABLE(SVG)
    116 #endif // SVGAnimatedListPropertyTearOff_h
    117