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 #include "config.h"
     21 
     22 #if ENABLE(SVG)
     23 #include "SVGPathSegListPropertyTearOff.h"
     24 
     25 #include "SVGAnimatedPathSegListPropertyTearOff.h"
     26 #include "SVGNames.h"
     27 #include "SVGPathElement.h"
     28 #include "SVGPathSegWithContext.h"
     29 
     30 namespace WebCore {
     31 
     32 void SVGPathSegListPropertyTearOff::clear(ExceptionCode& ec)
     33 {
     34     SVGPathSegList& values = m_animatedProperty->values();
     35     if (values.isEmpty())
     36         return;
     37 
     38     unsigned size = values.size();
     39     for (unsigned i = 0; i < size; ++i) {
     40         ListItemType item = values.at(i);
     41         static_cast<SVGPathSegWithContext*>(item.get())->setContextAndRole(0, PathSegUndefinedRole);
     42     }
     43 
     44     SVGPathSegListPropertyTearOff::Base::clearValues(values, ec);
     45 }
     46 
     47 SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::getItem(unsigned index, ExceptionCode& ec)
     48 {
     49     SVGPathSegList& values = m_animatedProperty->values();
     50     ListItemType returnedItem = Base::getItemValues(values, index, ec);
     51     if (returnedItem) {
     52         ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->contextElement() == contextElement());
     53         ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->role() == m_pathSegRole);
     54     }
     55     return returnedItem.release();
     56 }
     57 
     58 SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::removeItem(unsigned index, ExceptionCode& ec)
     59 {
     60     SVGPathSegList& values = m_animatedProperty->values();
     61     SVGPathSegListPropertyTearOff::ListItemType removedItem = SVGPathSegListPropertyTearOff::Base::removeItemValues(values, index, ec);
     62     if (removedItem)
     63         static_cast<SVGPathSegWithContext*>(removedItem.get())->setContextAndRole(0, PathSegUndefinedRole);
     64     return removedItem.release();
     65 }
     66 
     67 SVGPathElement* SVGPathSegListPropertyTearOff::contextElement() const
     68 {
     69     SVGElement* contextElement = m_animatedProperty->contextElement();
     70     ASSERT(contextElement);
     71     ASSERT(contextElement->hasTagName(SVGNames::pathTag));
     72     return static_cast<SVGPathElement*>(contextElement);
     73 }
     74 
     75 void SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify)
     76 {
     77     SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get());
     78     SVGAnimatedProperty* animatedPropertyOfItem = newItemWithContext->animatedProperty();
     79 
     80     // Alter the role, after calling animatedProperty(), as that may influence the returned animated property.
     81     newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole);
     82 
     83     if (!animatedPropertyOfItem)
     84         return;
     85 
     86     // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off.
     87     // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())")
     88     if (!animatedPropertyOfItem->isAnimatedListTearOff())
     89         return;
     90 
     91     // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
     92     // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal.
     93     bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty;
     94     int removedIndex = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem)->removeItemFromList(newItem.get(), livesInOtherList);
     95     ASSERT(removedIndex != -1);
     96 
     97     if (!indexToModify)
     98         return;
     99 
    100     // If the item lived in our list, adjust the insertion index.
    101     if (!livesInOtherList) {
    102         unsigned& index = *indexToModify;
    103         // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item.
    104         if (static_cast<unsigned>(removedIndex) < index)
    105             --index;
    106     }
    107 }
    108 
    109 }
    110 
    111 #endif // ENABLE(SVG)
    112