DOMSVGAnimatedTransformList.cpp (4378B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "DOMSVGAnimatedTransformList.h" 8 9 #include "DOMSVGTransformList.h" 10 #include "SVGAnimatedTransformList.h" 11 #include "SVGAttrTearoffTable.h" 12 #include "mozilla/dom/SVGAnimatedTransformListBinding.h" 13 14 namespace mozilla::dom { 15 16 constinit static SVGAttrTearoffTable<SVGAnimatedTransformList, 17 DOMSVGAnimatedTransformList> 18 sSVGAnimatedTransformListTearoffTable; 19 20 NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGAnimatedTransformList, 21 mElement) 22 23 JSObject* DOMSVGAnimatedTransformList::WrapObject( 24 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) { 25 return SVGAnimatedTransformList_Binding::Wrap(aCx, this, aGivenProto); 26 } 27 28 //---------------------------------------------------------------------- 29 already_AddRefed<DOMSVGTransformList> DOMSVGAnimatedTransformList::BaseVal() { 30 if (!mBaseVal) { 31 mBaseVal = new DOMSVGTransformList(this, InternalAList().GetBaseValue()); 32 } 33 RefPtr<DOMSVGTransformList> baseVal = mBaseVal; 34 return baseVal.forget(); 35 } 36 37 already_AddRefed<DOMSVGTransformList> DOMSVGAnimatedTransformList::AnimVal() { 38 if (!mAnimVal) { 39 mAnimVal = new DOMSVGTransformList(this, InternalAList().GetAnimValue()); 40 } 41 RefPtr<DOMSVGTransformList> animVal = mAnimVal; 42 return animVal.forget(); 43 } 44 45 /* static */ 46 already_AddRefed<DOMSVGAnimatedTransformList> 47 DOMSVGAnimatedTransformList::GetDOMWrapper(SVGAnimatedTransformList* aList, 48 SVGElement* aElement) { 49 RefPtr<DOMSVGAnimatedTransformList> wrapper = 50 sSVGAnimatedTransformListTearoffTable.GetTearoff(aList); 51 if (!wrapper) { 52 wrapper = new DOMSVGAnimatedTransformList(aElement); 53 sSVGAnimatedTransformListTearoffTable.AddTearoff(aList, wrapper); 54 } 55 return wrapper.forget(); 56 } 57 58 /* static */ 59 DOMSVGAnimatedTransformList* DOMSVGAnimatedTransformList::GetDOMWrapperIfExists( 60 SVGAnimatedTransformList* aList) { 61 return sSVGAnimatedTransformListTearoffTable.GetTearoff(aList); 62 } 63 64 DOMSVGAnimatedTransformList::~DOMSVGAnimatedTransformList() { 65 // Script no longer has any references to us, to our base/animVal objects, or 66 // to any of their list items. 67 sSVGAnimatedTransformListTearoffTable.RemoveTearoff(&InternalAList()); 68 } 69 70 void DOMSVGAnimatedTransformList::InternalBaseValListWillChangeLengthTo( 71 uint32_t aNewLength) { 72 // When the number of items in our internal counterpart's baseVal changes, 73 // we MUST keep our baseVal in sync. If we don't, script will either see a 74 // list that is too short and be unable to access indexes that should be 75 // valid, or else, MUCH WORSE, script will see a list that is too long and be 76 // able to access "items" at indexes that are out of bounds (read/write to 77 // bad memory)!! 78 79 RefPtr<DOMSVGAnimatedTransformList> kungFuDeathGrip; 80 if (mBaseVal) { 81 if (aNewLength < mBaseVal->LengthNoFlush()) { 82 // InternalListLengthWillChange might clear last reference to |this|. 83 // Retain a temporary reference to keep from dying before returning. 84 kungFuDeathGrip = this; 85 } 86 mBaseVal->InternalListLengthWillChange(aNewLength); 87 } 88 89 // If our attribute is not animating, then our animVal mirrors our baseVal 90 // and we must sync its length too. (If our attribute is animating, then the 91 // SMIL engine takes care of calling InternalAnimValListWillChangeLengthTo() 92 // if necessary.) 93 94 if (!IsAnimating()) { 95 InternalAnimValListWillChangeLengthTo(aNewLength); 96 } 97 } 98 99 void DOMSVGAnimatedTransformList::InternalAnimValListWillChangeLengthTo( 100 uint32_t aNewLength) { 101 if (mAnimVal) { 102 mAnimVal->InternalListLengthWillChange(aNewLength); 103 } 104 } 105 106 bool DOMSVGAnimatedTransformList::IsAnimating() const { 107 return InternalAList().IsAnimating(); 108 } 109 110 SVGAnimatedTransformList& DOMSVGAnimatedTransformList::InternalAList() { 111 return *mElement->GetAnimatedTransformList(); 112 } 113 114 const SVGAnimatedTransformList& DOMSVGAnimatedTransformList::InternalAList() 115 const { 116 return *mElement->GetAnimatedTransformList(); 117 } 118 119 } // namespace mozilla::dom