summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGPathSegList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/svg/SVGPathSegList.cpp')
-rw-r--r--Source/WebCore/svg/SVGPathSegList.cpp106
1 files changed, 92 insertions, 14 deletions
diff --git a/Source/WebCore/svg/SVGPathSegList.cpp b/Source/WebCore/svg/SVGPathSegList.cpp
index 705c968c0..403ce33a6 100644
--- a/Source/WebCore/svg/SVGPathSegList.cpp
+++ b/Source/WebCore/svg/SVGPathSegList.cpp
@@ -1,7 +1,4 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -21,29 +18,110 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "SVGPathSegList.h"
-#include "SVGNames.h"
+#include "SVGAnimatedPathSegListPropertyTearOff.h"
#include "SVGPathElement.h"
-#include "SVGPathUtilities.h"
+#include "SVGPathSegWithContext.h"
namespace WebCore {
-String SVGPathSegList::valueAsString() const
+void SVGPathSegList::clearContextAndRoles()
+{
+ ASSERT(m_values);
+ for (auto& item : *m_values)
+ static_cast<SVGPathSegWithContext*>(item.get())->setContextAndRole(nullptr, PathSegUndefinedRole);
+}
+
+ExceptionOr<void> SVGPathSegList::clear()
+{
+ ASSERT(m_values);
+ if (m_values->isEmpty())
+ return { };
+
+ clearContextAndRoles();
+ return Base::clearValues();
+}
+
+ExceptionOr<SVGPathSegList::PtrListItemType> SVGPathSegList::getItem(unsigned index)
{
- String pathString;
- buildStringFromSVGPathSegList(*this, pathString, UnalteredParsing);
- return pathString;
+ return Base::getItemValues(index);
}
-void SVGPathSegList::commitChange(SVGElement* contextElement, ListModification listModification)
+ExceptionOr<SVGPathSegList::PtrListItemType> SVGPathSegList::replaceItem(PtrListItemType newItem, unsigned index)
{
+ // Not specified, but FF/Opera do it this way, and it's just sane.
+ if (!newItem)
+ return Exception { SVGException::SVG_WRONG_TYPE_ERR };
+
+ if (index < m_values->size()) {
+ ListItemType replacedItem = m_values->at(index);
+ ASSERT(replacedItem);
+ static_cast<SVGPathSegWithContext*>(replacedItem.get())->setContextAndRole(nullptr, PathSegUndefinedRole);
+ }
+
+ return Base::replaceItemValues(newItem, index);
+}
+
+ExceptionOr<SVGPathSegList::PtrListItemType> SVGPathSegList::removeItem(unsigned index)
+{
+ auto result = Base::removeItemValues(index);
+ if (result.hasException())
+ return result;
+ auto removedItem = result.releaseReturnValue();
+ if (removedItem)
+ static_cast<SVGPathSegWithContext&>(*removedItem).setContextAndRole(nullptr, PathSegUndefinedRole);
+ return WTFMove(removedItem);
+}
+
+SVGPathElement* SVGPathSegList::contextElement() const
+{
+ SVGElement* contextElement = m_animatedProperty->contextElement();
ASSERT(contextElement);
- toSVGPathElement(contextElement)->pathSegListChanged(m_role, listModification);
+ return downcast<SVGPathElement>(contextElement);
}
+bool SVGPathSegList::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify)
+{
+ SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get());
+ RefPtr<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;
+ RefPtr<SVGAnimatedPathSegListPropertyTearOff> propertyTearOff = static_pointer_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;
}
-#endif // ENABLE(SVG)
+}