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 SVGPathSegListPropertyTearOff_h
     21 #define SVGPathSegListPropertyTearOff_h
     22 
     23 #include "bindings/v8/ExceptionState.h"
     24 #include "core/svg/SVGPathSegList.h"
     25 #include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
     26 
     27 namespace WebCore {
     28 
     29 class SVGPathElement;
     30 
     31 class SVGPathSegListPropertyTearOff : public SVGListProperty<SVGPathSegList> {
     32 public:
     33     typedef SVGListProperty<SVGPathSegList> Base;
     34     typedef SVGAnimatedListPropertyTearOff<SVGPathSegList> AnimatedListPropertyTearOff;
     35     typedef SVGPropertyTraits<SVGPathSegList>::ListItemType ListItemType;
     36     typedef PassRefPtr<SVGPathSeg> PassListItemType;
     37 
     38     static PassRefPtr<SVGPathSegListPropertyTearOff> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers)
     39     {
     40         ASSERT(animatedProperty);
     41         return adoptRef(new SVGPathSegListPropertyTearOff(animatedProperty, role, pathSegRole, values, wrappers));
     42     }
     43 
     44     SVGPathElement* contextElement() const;
     45     SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty; }
     46 
     47     int findItem(const ListItemType& item) const
     48     {
     49         ASSERT(m_values);
     50 
     51         unsigned size = m_values->size();
     52         for (size_t i = 0; i < size; ++i) {
     53             if (item == m_values->at(i))
     54                 return i;
     55         }
     56 
     57         return -1;
     58     }
     59 
     60     void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
     61     {
     62         ASSERT(m_values);
     63         ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_values->size());
     64 
     65         m_values->remove(itemIndex);
     66 
     67         if (shouldSynchronizeWrappers)
     68             commitChange();
     69     }
     70 
     71     // SVGList API
     72     void clear(ExceptionState&);
     73 
     74     PassListItemType initialize(PassListItemType passNewItem, ExceptionState& exceptionState)
     75     {
     76         // Not specified, but FF/Opera do it this way, and it's just sane.
     77         if (!passNewItem) {
     78             exceptionState.throwUninformativeAndGenericTypeError();
     79             return 0;
     80         }
     81 
     82         clearContextAndRoles();
     83         ListItemType newItem = passNewItem;
     84         return Base::initializeValues(newItem, exceptionState);
     85     }
     86 
     87     PassListItemType getItem(unsigned index, ExceptionState&);
     88 
     89     PassListItemType insertItemBefore(PassListItemType passNewItem, unsigned index, ExceptionState& exceptionState)
     90     {
     91         // Not specified, but FF/Opera do it this way, and it's just sane.
     92         if (!passNewItem) {
     93             exceptionState.throwUninformativeAndGenericTypeError();
     94             return 0;
     95         }
     96 
     97         ListItemType newItem = passNewItem;
     98         return Base::insertItemBeforeValues(newItem, index, exceptionState);
     99     }
    100 
    101     PassListItemType replaceItem(PassListItemType, unsigned index, ExceptionState&);
    102 
    103     PassListItemType removeItem(unsigned index, ExceptionState&);
    104 
    105     PassListItemType appendItem(PassListItemType passNewItem, ExceptionState& exceptionState)
    106     {
    107         // Not specified, but FF/Opera do it this way, and it's just sane.
    108         if (!passNewItem) {
    109             exceptionState.throwUninformativeAndGenericTypeError();
    110             return 0;
    111         }
    112 
    113         ListItemType newItem = passNewItem;
    114         return Base::appendItemValues(newItem, exceptionState);
    115     }
    116 
    117 private:
    118     SVGPathSegListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers)
    119         : SVGListProperty<SVGPathSegList>(role, values, &wrappers)
    120         , m_animatedProperty(animatedProperty)
    121         , m_pathSegRole(pathSegRole)
    122     {
    123     }
    124 
    125     void clearContextAndRoles();
    126 
    127     using Base::m_role;
    128 
    129     virtual bool isReadOnly() const
    130     {
    131         if (m_role == AnimValRole)
    132             return true;
    133         if (m_animatedProperty && m_animatedProperty->isReadOnly())
    134             return true;
    135         return false;
    136     }
    137 
    138     virtual void commitChange()
    139     {
    140         ASSERT(m_values);
    141         m_values->commitChange(m_animatedProperty->contextElement(), ListModificationUnknown);
    142     }
    143 
    144     virtual void commitChange(ListModification listModification)
    145     {
    146         ASSERT(m_values);
    147         m_values->commitChange(m_animatedProperty->contextElement(), listModification);
    148     }
    149 
    150     virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) OVERRIDE;
    151     virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*)
    152     {
    153         ASSERT_NOT_REACHED();
    154         return true;
    155     }
    156 
    157 private:
    158     AnimatedListPropertyTearOff* m_animatedProperty;
    159     SVGPathSegRole m_pathSegRole;
    160 };
    161 
    162 }
    163 
    164 #endif // SVGListPropertyTearOff_h
    165