void nsSVGAnimatedTransformList::ClearAnimValue(nsSVGElement *aElement) { SVGAnimatedTransformList *domWrapper = SVGAnimatedTransformList::GetDOMWrapperIfExists(this); if (domWrapper) { // When all animation ends, animVal simply mirrors baseVal, which may have // a different number of items to the last active animated value. We must // keep the length of our animVal's DOM wrapper list in sync, and again we // must do that before touching mAnimVal. See comments above. // domWrapper->InternalAnimValListWillChangeLengthTo(mBaseVal.Length()); } mAnimVal = nullptr; aElement->DidAnimateTransformList(); }
nsresult nsSVGAnimatedTransformList::SetAnimValue(const SVGTransformList& aValue, nsSVGElement *aElement) { bool prevSet = HasTransform() || aElement->GetAnimateMotionTransform(); SVGAnimatedTransformList *domWrapper = SVGAnimatedTransformList::GetDOMWrapperIfExists(this); if (domWrapper) { // A new animation may totally change the number of items in the animVal // list, replacing what was essentially a mirror of the baseVal list, or // else replacing and overriding an existing animation. When this happens // we must try and keep our animVal's DOM wrapper in sync (see the comment // in SVGAnimatedTransformList::InternalBaseValListWillChangeLengthTo). // // It's not possible for us to reliably distinguish between calls to this // method that are setting a new sample for an existing animation, and // calls that are setting the first sample of an animation that will // override an existing animation. Happily it's cheap to just blindly // notify our animVal's DOM wrapper of its internal counterpart's new value // each time this method is called, so that's what we do. // // Note that we must send this notification *before* setting or changing // mAnimVal! (See the comment in SetBaseValueString above.) // domWrapper->InternalAnimValListWillChangeLengthTo(aValue.Length()); } if (!mAnimVal) { mAnimVal = new SVGTransformList(); } nsresult rv = mAnimVal->CopyFrom(aValue); if (NS_FAILED(rv)) { // OOM. We clear the animation, and, importantly, ClearAnimValue() ensures // that mAnimVal and its DOM wrapper (if any) will have the same length! ClearAnimValue(aElement); return rv; } int32_t modType; if(prevSet) { modType = nsIDOMMutationEvent::MODIFICATION; } else { modType = nsIDOMMutationEvent::ADDITION; } aElement->DidAnimateTransformList(modType); return NS_OK; }
void nsSVGAnimatedTransformList::ClearAnimValue(nsSVGElement *aElement) { SVGAnimatedTransformList *domWrapper = SVGAnimatedTransformList::GetDOMWrapperIfExists(this); if (domWrapper) { // When all animation ends, animVal simply mirrors baseVal, which may have // a different number of items to the last active animated value. We must // keep the length of our animVal's DOM wrapper list in sync, and again we // must do that before touching mAnimVal. See comments above. // domWrapper->InternalAnimValListWillChangeLengthTo(mBaseVal.Length()); } mAnimVal = nullptr; int32_t modType; if (HasTransform() || aElement->GetAnimateMotionTransform()) { modType = nsIDOMMutationEvent::MODIFICATION; } else { modType = nsIDOMMutationEvent::REMOVAL; } aElement->DidAnimateTransformList(modType); }