bool SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) { SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get()); SVGAnimatedProperty* animatedPropertyOfItem = newItemWithContext->animatedProperty(); // Alter the role, after calling animatedProperty(), as that may influence the returned animated property. newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole); if (!animatedPropertyOfItem) return true; // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off. // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())") if (!animatedPropertyOfItem->isAnimatedListTearOff()) return true; // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal. bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty; SVGAnimatedPathSegListPropertyTearOff* propertyTearOff = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem); int indexToRemove = propertyTearOff->findItem(newItem.get()); ASSERT(indexToRemove != -1); // Do not remove newItem if already in this list at the target index. if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify) return false; propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList); if (!indexToModify) return true; // If the item lived in our list, adjust the insertion index. if (!livesInOtherList) { unsigned& index = *indexToModify; // 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. if (static_cast<unsigned>(indexToRemove) < index) --index; } return true; }
PassOwnPtr<SVGAnimatedType> SVGAnimatedPathAnimator::startAnimValAnimation(const Vector<SVGAnimatedProperty*>& properties) { ASSERT(properties.size() == 1); SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(properties[0]); const SVGPathSegList& baseValue = property->currentBaseValue(); // Build initial path byte stream. OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); SVGPathParserFactory::self()->buildSVGPathByteStreamFromSVGPathSegList(baseValue, byteStream.get(), UnalteredParsing); Vector<SVGAnimatedPathSegListPropertyTearOff*> result; result.append(property); SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement()); collectAnimatedPropertiesFromInstances(result, 0, property->contextElement(), property->attributeName()); size_t resultSize = result.size(); for (size_t i = 0; i < resultSize; ++i) result[i]->animationStarted(byteStream.get(), &baseValue); return SVGAnimatedType::createPath(byteStream.release()); }
PassOwnPtr<SVGAnimatedType> SVGAnimatedPathAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes) { ASSERT(animatedTypes.size() >= 1); SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get()); const SVGPathSegList& baseValue = property->currentBaseValue(); // Build initial path byte stream. OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create(); buildSVGPathByteStreamFromSVGPathSegList(baseValue, byteStream.get(), UnalteredParsing); Vector<RefPtr<SVGAnimatedPathSegListPropertyTearOff> > result; SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end(); for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) result.append(castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(it->properties[0].get())); SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement()); size_t resultSize = result.size(); for (size_t i = 0; i < resultSize; ++i) result[i]->animationStarted(byteStream.get(), &baseValue); return SVGAnimatedType::createPath(byteStream.release()); }