DOMSVGPointList::~DOMSVGPointList() { // There are now no longer any references to us held by script or list items. // Note we must use GetAnimValKey/GetBaseValKey here, NOT InternalList()! void *key = mIsAnimValList ? InternalAList().GetAnimValKey() : InternalAList().GetBaseValKey(); SVGPointListTearoffTable().RemoveTearoff(key); }
void DOMSVGPathSegList:: MaybeRemoveItemFromAnimValListAt(uint32_t aIndex, int32_t aArgCountForItem) { MOZ_ASSERT(!IsAnimValList(), "call from baseVal to animVal"); if (AttrIsAnimating()) { // animVal not a clone of baseVal return; } // This needs to be a strong reference; otherwise, the RemovingFromList call // below might drop the last reference to animVal before we're done with it. nsRefPtr<DOMSVGPathSegList> animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (!animVal) { // No animVal list wrapper return; } MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); if (animVal->ItemAt(aIndex)) { animVal->ItemAt(aIndex)->RemovingFromList(); } animVal->mItems.RemoveElementAt(aIndex); animVal->UpdateListIndicesFromIndex(aIndex, -(1 + aArgCountForItem)); }
void DOMSVGPointList::MaybeRemoveItemFromAnimValListAt(uint32_t aIndex) { MOZ_ASSERT(!IsAnimValList(), "call from baseVal to animVal"); if (!AnimListMirrorsBaseList()) { return; } // This needs to be a strong reference; otherwise, the RemovingFromList call // below might drop the last reference to animVal before we're done with it. RefPtr<DOMSVGPointList> animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); MOZ_ASSERT(animVal, "AnimListMirrorsBaseList() promised a non-null animVal"); MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); if (animVal->mItems[aIndex]) { animVal->mItems[aIndex]->RemovingFromList(); } animVal->mItems.RemoveElementAt(aIndex); UpdateListIndicesFromIndex(animVal->mItems, aIndex); }
void DOMSVGPathSegList:: MaybeInsertNullInAnimValListAt(uint32_t aIndex, uint32_t aInternalIndex, uint32_t aArgCountForItem) { NS_ABORT_IF_FALSE(!IsAnimValList(), "call from baseVal to animVal"); if (AttrIsAnimating()) { // animVal not a clone of baseVal return; } // The anim val list is in sync with the base val list DOMSVGPathSegList *animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (!animVal) { // No animVal list wrapper return; } NS_ABORT_IF_FALSE(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); animVal->mItems.InsertElementAt(aIndex, ItemProxy(nullptr, aInternalIndex)); animVal->UpdateListIndicesFromIndex(aIndex + 1, 1 + aArgCountForItem); }
void DOMSVGPathSegList:: MaybeRemoveItemFromAnimValListAt(PRUint32 aIndex, PRUint32 aArgCountForItem) { NS_ABORT_IF_FALSE(!IsAnimValList(), "call from baseVal to animVal"); if (AttrIsAnimating()) { // animVal not a clone of baseVal return; } DOMSVGPathSegList *animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (!animVal) { // No animVal list wrapper return; } NS_ABORT_IF_FALSE(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); if (animVal->ItemAt(aIndex)) { animVal->ItemAt(aIndex)->RemovingFromList(); } animVal->mItems.RemoveElementAt(aIndex); animVal->UpdateListIndicesFromIndex(aIndex, -(1 + aArgCountForItem)); }
NS_IMETHODIMP DOMSVGPointList::Clear() { if (IsAnimValList()) { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; } if (Length() > 0) { // DOM list items that are to be removed must be removed before we change // the internal list, otherwise they wouldn't be able to copy their // internal counterparts' values! InternalListWillChangeTo(SVGPointList()); // clears mItems if (!AttrIsAnimating()) { // The anim val list is in sync with the base val list DOMSVGPointList *animList = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (animList) { animList->InternalListWillChangeTo(SVGPointList()); // clears its mItems } } InternalList().Clear(); Element()->DidChangePointList(true); if (AttrIsAnimating()) { Element()->AnimationNeedsResample(); } } return NS_OK; }
void DOMSVGPointList::MaybeRemoveItemFromAnimValListAt(uint32_t aIndex) { NS_ABORT_IF_FALSE(!IsAnimValList(), "call from baseVal to animVal"); if (AttrIsAnimating()) { // animVal not a clone of baseVal return; } // This needs to be a strong reference; otherwise, the RemovingFromList call // below might drop the last reference to animVal before we're done with it. nsRefPtr<DOMSVGPointList> animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (!animVal) { // No animVal list wrapper return; } NS_ABORT_IF_FALSE(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); if (animVal->mItems[aIndex]) { animVal->mItems[aIndex]->RemovingFromList(); } animVal->mItems.RemoveElementAt(aIndex); UpdateListIndicesFromIndex(animVal->mItems, aIndex); }
void DOMSVGPointList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) { MOZ_ASSERT(!IsAnimValList(), "call from baseVal to animVal"); if (AttrIsAnimating()) { // animVal not a clone of baseVal return; } // The anim val list is in sync with the base val list DOMSVGPointList *animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (!animVal) { // No animVal list wrapper return; } MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, nullptr, fallible)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); }
void DOMSVGPointList::Clear(ErrorResult& aError) { if (IsAnimValList()) { aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return; } if (LengthNoFlush() > 0) { AutoChangePointListNotifier notifier(this); // DOM list items that are to be removed must be removed before we change // the internal list, otherwise they wouldn't be able to copy their // internal counterparts' values! InternalListWillChangeTo(SVGPointList()); // clears mItems if (!AttrIsAnimating()) { // The anim val list is in sync with the base val list DOMSVGPointList *animList = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (animList) { animList->InternalListWillChangeTo(SVGPointList()); // clears its mItems } } InternalList().Clear(); } }
void DOMSVGPathSegList::Clear(ErrorResult& aError) { if (IsAnimValList()) { aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return; } if (LengthNoFlush() > 0) { nsAttrValue emptyOrOldValue = Element()->WillChangePathSegList(); // DOM list items that are to be removed must be removed before we change // the internal list, otherwise they wouldn't be able to copy their // internal counterparts' values! InternalListWillChangeTo(SVGPathData()); // clears mItems if (!AttrIsAnimating()) { // The anim val list is in sync with the base val list DOMSVGPathSegList *animList = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (animList) { animList->InternalListWillChangeTo(SVGPathData()); // clears its mItems } } InternalList().Clear(); Element()->DidChangePathSegList(emptyOrOldValue); if (AttrIsAnimating()) { Element()->AnimationNeedsResample(); } } }
void DOMSVGPointList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) { NS_ABORT_IF_FALSE(!IsAnimValList(), "call from baseVal to animVal"); if (AttrIsAnimating()) { // animVal not a clone of baseVal return; } // The anim val list is in sync with the base val list DOMSVGPointList *animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); if (!animVal) { // No animVal list wrapper return; } NS_ABORT_IF_FALSE(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); animVal->mItems.InsertElementAt(aIndex, static_cast<nsISVGPoint*>(nullptr)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); }
NS_IMETHODIMP DOMSVGAnimatedLengthList::GetAnimVal(nsIDOMSVGLengthList **_retval) { if (!mAnimVal) { mAnimVal = new DOMSVGLengthList(this, InternalAList().GetAnimValue()); } NS_ADDREF(*_retval = mAnimVal); return NS_OK; }
/* readonly attribute nsIDOMSVGTransformList animVal; */ NS_IMETHODIMP DOMSVGAnimatedTransformList::GetAnimVal(nsIDOMSVGTransformList** aAnimVal) { if (!mAnimVal) { mAnimVal = new DOMSVGTransformList(this, InternalAList().GetAnimValue()); } NS_ADDREF(*aAnimVal = mAnimVal); return NS_OK; }
already_AddRefed<nsISVGPoint> DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex, ErrorResult& aError) { if (IsAnimValList()) { aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return nullptr; } aIndex = std::min(aIndex, LengthNoFlush()); if (aIndex >= nsISVGPoint::MaxListIndex()) { aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return nullptr; } nsCOMPtr<nsISVGPoint> domItem = &aNewItem; if (domItem->HasOwner() || domItem->IsReadonly() || domItem->IsTranslatePoint()) { domItem = domItem->Copy(); // must do this before changing anything! } // Ensure we have enough memory so we can avoid complex error handling below: if (!mItems.SetCapacity(mItems.Length() + 1, fallible) || !InternalList().SetCapacity(InternalList().Length() + 1)) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } if (AnimListMirrorsBaseList()) { DOMSVGPointList *animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); MOZ_ASSERT(animVal, "animVal must be a valid pointer"); if (!animVal->mItems.SetCapacity( animVal->mItems.Length() + 1, fallible)) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return nullptr; } } AutoChangePointListNotifier notifier(this); // Now that we know we're inserting, keep animVal list in sync as necessary. MaybeInsertNullInAnimValListAt(aIndex); InternalList().InsertItem(aIndex, domItem->ToSVGPoint()); MOZ_ALWAYS_TRUE(mItems.InsertElementAt(aIndex, domItem, fallible)); // This MUST come after the insertion into InternalList(), or else under the // insertion into InternalList() the values read from domItem would be bad // data from InternalList() itself!: domItem->InsertingIntoList(this, aIndex, IsAnimValList()); UpdateListIndicesFromIndex(mItems, aIndex + 1); return domItem.forget(); }
NS_INTERFACE_MAP_END NS_IMETHODIMP DOMSVGAnimatedLengthList::GetBaseVal(nsIDOMSVGLengthList **_retval) { if (!mBaseVal) { mBaseVal = new DOMSVGLengthList(this, InternalAList().GetBaseValue()); } NS_ADDREF(*_retval = mBaseVal); return NS_OK; }
NS_INTERFACE_MAP_END //---------------------------------------------------------------------- // nsIDOMSVGAnimatedTransformList methods: /* readonly attribute nsIDOMSVGTransformList baseVal; */ NS_IMETHODIMP DOMSVGAnimatedTransformList::GetBaseVal(nsIDOMSVGTransformList** aBaseVal) { if (!mBaseVal) { mBaseVal = new DOMSVGTransformList(this, InternalAList().GetBaseValue()); } NS_ADDREF(*aBaseVal = mBaseVal); return NS_OK; }
void DOMSVGPointList::MaybeInsertNullInAnimValListAt(uint32_t aIndex) { MOZ_ASSERT(!IsAnimValList(), "call from baseVal to animVal"); if (!AnimListMirrorsBaseList()) { return; } // The anim val list is in sync with the base val list DOMSVGPointList *animVal = GetDOMWrapperIfExists(InternalAList().GetAnimValKey()); MOZ_ASSERT(animVal, "AnimListMirrorsBaseList() promised a non-null animVal"); MOZ_ASSERT(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); MOZ_ALWAYS_TRUE(animVal->mItems.InsertElementAt(aIndex, nullptr, fallible)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); }
bool DOMSVGAnimatedLengthList::IsAnimating() const { return InternalAList().IsAnimating(); }
bool SVGAnimatedTransformList::IsAnimating() const { return InternalAList().IsAnimating(); }
bool DOMSVGPointList::AnimListMirrorsBaseList() const { return GetDOMWrapperIfExists(InternalAList().GetAnimValKey()) && !AttrIsAnimating(); }
bool DOMSVGPointList::AttrIsAnimating() const { return InternalAList().IsAnimating(); }
bool DOMSVGAnimatedNumberList::IsAnimating() const { return InternalAList().IsAnimating(); }
DOMSVGAnimatedNumberList::~DOMSVGAnimatedNumberList() { // Script no longer has any references to us, to our base/animVal objects, or // to any of their list items. SVGAnimatedNumberListTearoffTable().RemoveTearoff(&InternalAList()); }