diff options
Diffstat (limited to 'Source/WebCore/svg/properties/SVGListProperty.h')
-rw-r--r-- | Source/WebCore/svg/properties/SVGListProperty.h | 269 |
1 files changed, 137 insertions, 132 deletions
diff --git a/Source/WebCore/svg/properties/SVGListProperty.h b/Source/WebCore/svg/properties/SVGListProperty.h index 80c4b62d8..9b0d42032 100644 --- a/Source/WebCore/svg/properties/SVGListProperty.h +++ b/Source/WebCore/svg/properties/SVGListProperty.h @@ -17,13 +17,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SVGListProperty_h -#define SVGListProperty_h +#pragma once -#if ENABLE(SVG) +#include "ExceptionCode.h" #include "SVGException.h" #include "SVGPropertyTearOff.h" #include "SVGPropertyTraits.h" +#include <wtf/Ref.h> namespace WebCore { @@ -43,18 +43,15 @@ class SVGListProperty : public SVGProperty { public: typedef SVGListProperty<PropertyType> Self; - typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType; - typedef SVGPropertyTearOff<ListItemType> ListItemTearOff; - typedef PassRefPtr<ListItemTearOff> PassListItemTearOff; - typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff; - typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache; + using ListItemType = typename SVGPropertyTraits<PropertyType>::ListItemType; + using ListItemTearOff = typename SVGPropertyTraits<PropertyType>::ListItemTearOff; + using AnimatedListPropertyTearOff = SVGAnimatedListPropertyTearOff<PropertyType>; + using ListWrapperCache = typename AnimatedListPropertyTearOff::ListWrapperCache; - bool canAlterList(ExceptionCode& ec) const + ExceptionOr<bool> canAlterList() const { - if (m_role == AnimValRole) { - ec = NO_MODIFICATION_ALLOWED_ERR; - return false; - } + if (m_role == AnimValRole) + return Exception { NO_MODIFICATION_ALLOWED_ERR }; return true; } @@ -63,9 +60,8 @@ public: { // See SVGPropertyTearOff::detachWrapper() for an explanation about what's happening here. ASSERT(wrappers); - unsigned size = wrappers->size(); - for (unsigned i = 0; i < size; ++i) { - if (ListItemTearOff* item = wrappers->at(i).get()) + for (auto& item : *wrappers) { + if (item) item->detachWrapper(); } @@ -97,23 +93,29 @@ public: } // SVGList::clear() - void clearValues(ExceptionCode& ec) + ExceptionOr<void> clearValues() { - if (!canAlterList(ec)) - return; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); m_values->clear(); commitChange(); + return { }; } - void clearValuesAndWrappers(ExceptionCode& ec) + ExceptionOr<void> clearValuesAndWrappers() { - if (!canAlterList(ec)) - return; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); detachListWrappers(0); m_values->clear(); commitChange(); + return { }; } // SVGList::numberOfItems() @@ -123,10 +125,12 @@ public: } // SVGList::initialize() - ListItemType initializeValues(const ListItemType& newItem, ExceptionCode& ec) + ExceptionOr<ListItemType> initializeValues(const ListItemType& newItem) { - if (!canAlterList(ec)) - return ListItemType(); + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemValue(newItem, 0); @@ -136,24 +140,22 @@ public: m_values->append(newItem); commitChange(); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff initializeValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> initializeValuesAndWrappers(ListItemTearOff& item) { ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - RefPtr<ListItemTearOff> newItem = passNewItem; ASSERT(m_values->size() == m_wrappers->size()); + Ref<ListItemTearOff> newItem(item); + // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemWrapper(newItem, 0); @@ -162,37 +164,40 @@ public: m_values->clear(); m_values->append(newItem->propertyReference()); - m_wrappers->append(newItem); + m_wrappers->append(newItem.ptr()); commitChange(); - return newItem.release(); + return WTFMove(newItem); } // SVGList::getItem() - bool canGetItem(unsigned index, ExceptionCode& ec) + ExceptionOr<bool> canGetItem(unsigned index) { - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return false; - } + if (index >= m_values->size()) + return Exception { INDEX_SIZE_ERR }; return true; } - ListItemType getItemValues(unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> getItemValues(unsigned index) { - if (!canGetItem(index, ec)) - return ListItemType(); + auto result = canGetItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. - return m_values->at(index); + return ListItemType { m_values->at(index) }; } - PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> getItemValuesAndWrappers(AnimatedListPropertyTearOff& animatedList, unsigned index) { ASSERT(m_wrappers); - if (!canGetItem(index, ec)) - return 0; + + auto result = canGetItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy. // Any changes made to the item are immediately reflected in the list. @@ -206,14 +211,16 @@ public: m_wrappers->at(index) = wrapper; } - return wrapper.release(); + return wrapper.releaseNonNull(); } // SVGList::insertItemBefore() - ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> insertItemBeforeValues(const ListItemType& newItem, unsigned index) { - if (!canAlterList(ec)) - return ListItemType(); + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. if (index > m_values->size()) @@ -222,7 +229,7 @@ public: // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. if (!processIncomingListItemValue(newItem, &index)) { // Inserting the item before itself is a no-op. - return newItem; + return ListItemType { newItem }; } // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be @@ -230,107 +237,103 @@ public: m_values->insert(index, newItem); commitChange(); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> insertItemBeforeValuesAndWrappers(ListItemTearOff& item, unsigned index) { ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list. if (index > m_values->size()) - index = m_values->size(); + index = m_values->size(); - RefPtr<ListItemTearOff> newItem = passNewItem; ASSERT(m_values->size() == m_wrappers->size()); + Ref<ListItemTearOff> newItem(item); + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. if (!processIncomingListItemWrapper(newItem, &index)) - return newItem.release(); + return WTFMove(newItem); // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list. m_values->insert(index, newItem->propertyReference()); // Store new wrapper at position 'index', change its underlying value, so mutations of newItem, directly affect the item in the list. - m_wrappers->insert(index, newItem); + m_wrappers->insert(index, newItem.ptr()); commitChange(); - return newItem.release(); + return WTFMove(newItem); } // SVGList::replaceItem() - bool canReplaceItem(unsigned index, ExceptionCode& ec) + ExceptionOr<bool> canReplaceItem(unsigned index) { - if (!canAlterList(ec)) - return false; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return false; - } + if (index >= m_values->size()) + return Exception { INDEX_SIZE_ERR }; return true; } - ListItemType replaceItemValues(const ListItemType& newItem, unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> replaceItemValues(const ListItemType& newItem, unsigned index) { - if (!canReplaceItem(index, ec)) - return ListItemType(); + auto result = canReplaceItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. if (!processIncomingListItemValue(newItem, &index)) { // Replacing the item with itself is a no-op. - return newItem; + return ListItemType { newItem }; } if (m_values->isEmpty()) { // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. - ec = INDEX_SIZE_ERR; - return ListItemType(); + return Exception { INDEX_SIZE_ERR }; } // Update the value at the desired position 'index'. m_values->at(index) = newItem; commitChange(); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff replaceItemValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> replaceItemValuesAndWrappers(ListItemTearOff& item, unsigned index) { ASSERT(m_wrappers); - if (!canReplaceItem(index, ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canReplaceItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); ASSERT(m_values->size() == m_wrappers->size()); - RefPtr<ListItemTearOff> newItem = passNewItem; + + Ref<ListItemTearOff> newItem(item); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item. if (!processIncomingListItemWrapper(newItem, &index)) - return newItem.release(); + return WTFMove(newItem); if (m_values->isEmpty()) { ASSERT(m_wrappers->isEmpty()); - // 'passNewItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. - ec = INDEX_SIZE_ERR; - return 0; + // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace. + return Exception { INDEX_SIZE_ERR }; } // Detach the existing wrapper. @@ -340,43 +343,48 @@ public: // Update the value and the wrapper at the desired position 'index'. m_values->at(index) = newItem->propertyReference(); - m_wrappers->at(index) = newItem; + m_wrappers->at(index) = newItem.ptr(); commitChange(); - return newItem.release(); + return WTFMove(newItem); } // SVGList::removeItem() - bool canRemoveItem(unsigned index, ExceptionCode& ec) + ExceptionOr<bool> canRemoveItem(unsigned index) { - if (!canAlterList(ec)) - return false; + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - if (index >= m_values->size()) { - ec = INDEX_SIZE_ERR; - return false; - } + if (index >= m_values->size()) + return Exception { INDEX_SIZE_ERR }; return true; } - ListItemType removeItemValues(unsigned index, ExceptionCode& ec) + ExceptionOr<ListItemType> removeItemValues(unsigned index) { - if (!canRemoveItem(index, ec)) - return ListItemType(); + auto result = canRemoveItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); ListItemType oldItem = m_values->at(index); m_values->remove(index); commitChange(); - return oldItem; + return WTFMove(oldItem); } - PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> removeItemValuesAndWrappers(AnimatedListPropertyTearOff& animatedList, unsigned index) { ASSERT(m_wrappers); - if (!canRemoveItem(index, ec)) - return 0; + + auto result = canRemoveItem(index); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); ASSERT(m_values->size() == m_wrappers->size()); @@ -390,14 +398,16 @@ public: m_values->remove(index); commitChange(); - return oldItem.release(); + return oldItem.releaseNonNull(); } // SVGList::appendItem() - ListItemType appendItemValues(const ListItemType& newItem, ExceptionCode& ec) + ExceptionOr<ListItemType> appendItemValues(const ListItemType& newItem) { - if (!canAlterList(ec)) - return ListItemType(); + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemValue(newItem, 0); @@ -406,33 +416,31 @@ public: m_values->append(newItem); commitChange(ListModificationAppend); - return newItem; + return ListItemType { newItem }; } - PassListItemTearOff appendItemValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionCode& ec) + ExceptionOr<Ref<ListItemTearOff>> appendItemValuesAndWrappers(ListItemTearOff& item) { ASSERT(m_wrappers); - if (!canAlterList(ec)) - return 0; - // Not specified, but FF/Opera do it this way, and it's just sane. - if (!passNewItem) { - ec = SVGException::SVG_WRONG_TYPE_ERR; - return 0; - } + auto result = canAlterList(); + if (result.hasException()) + return result.releaseException(); + ASSERT(result.releaseReturnValue()); - RefPtr<ListItemTearOff> newItem = passNewItem; ASSERT(m_values->size() == m_wrappers->size()); + Ref<ListItemTearOff> newItem(item); + // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list. processIncomingListItemWrapper(newItem, 0); // Append the value and wrapper at the end of the list. m_values->append(newItem->propertyReference()); - m_wrappers->append(newItem); + m_wrappers->append(newItem.ptr()); commitChange(ListModificationAppend); - return newItem.release(); + return WTFMove(newItem); } PropertyType& values() @@ -462,14 +470,14 @@ protected: delete m_values; } - virtual void commitChange() = 0; + void commitChange() override = 0; virtual void commitChange(ListModification) { commitChange(); } virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0; - virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; + virtual bool processIncomingListItemWrapper(Ref<ListItemTearOff>& newItem, unsigned* indexToModify) = 0; SVGPropertyRole m_role; bool m_ownsValues; @@ -478,6 +486,3 @@ protected: }; } - -#endif // ENABLE(SVG) -#endif // SVGListProperty_h |