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 30namespace WebCore { 31 32void 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 47SVGPathSegListPropertyTearOff::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 58SVGPathSegListPropertyTearOff::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 67SVGPathElement* 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 75void 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