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/. */
7 #include "DOMSVGAnimatedNumberList.h"
9 #include "DOMSVGNumberList.h"
10 #include "SVGAnimatedNumberList.h"
11 #include "SVGAttrTearoffTable.h"
12 #include "mozilla/dom/SVGAnimatedNumberListBinding.h"
13 #include "mozilla/dom/SVGElement.h"
14 #include "mozilla/RefPtr.h"
16 // See the architecture comment in this file's header.
18 namespace mozilla::dom
{
20 static inline SVGAttrTearoffTable
<SVGAnimatedNumberList
,
21 DOMSVGAnimatedNumberList
>&
22 SVGAnimatedNumberListTearoffTable() {
23 static SVGAttrTearoffTable
<SVGAnimatedNumberList
, DOMSVGAnimatedNumberList
>
24 sSVGAnimatedNumberListTearoffTable
;
25 return sSVGAnimatedNumberListTearoffTable
;
28 NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGAnimatedNumberList
,
31 JSObject
* DOMSVGAnimatedNumberList::WrapObject(
32 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
33 return mozilla::dom::SVGAnimatedNumberList_Binding::Wrap(aCx
, this,
37 already_AddRefed
<DOMSVGNumberList
> DOMSVGAnimatedNumberList::BaseVal() {
39 mBaseVal
= new DOMSVGNumberList(this, InternalAList().GetBaseValue());
41 RefPtr
<DOMSVGNumberList
> baseVal
= mBaseVal
;
42 return baseVal
.forget();
45 already_AddRefed
<DOMSVGNumberList
> DOMSVGAnimatedNumberList::AnimVal() {
47 mAnimVal
= new DOMSVGNumberList(this, InternalAList().GetAnimValue());
49 RefPtr
<DOMSVGNumberList
> animVal
= mAnimVal
;
50 return animVal
.forget();
54 already_AddRefed
<DOMSVGAnimatedNumberList
>
55 DOMSVGAnimatedNumberList::GetDOMWrapper(SVGAnimatedNumberList
* aList
,
56 dom::SVGElement
* aElement
,
58 RefPtr
<DOMSVGAnimatedNumberList
> wrapper
=
59 SVGAnimatedNumberListTearoffTable().GetTearoff(aList
);
61 wrapper
= new DOMSVGAnimatedNumberList(aElement
, aAttrEnum
);
62 SVGAnimatedNumberListTearoffTable().AddTearoff(aList
, wrapper
);
64 return wrapper
.forget();
68 DOMSVGAnimatedNumberList
* DOMSVGAnimatedNumberList::GetDOMWrapperIfExists(
69 SVGAnimatedNumberList
* aList
) {
70 return SVGAnimatedNumberListTearoffTable().GetTearoff(aList
);
73 DOMSVGAnimatedNumberList::~DOMSVGAnimatedNumberList() {
74 // Script no longer has any references to us, to our base/animVal objects, or
75 // to any of their list items.
76 SVGAnimatedNumberListTearoffTable().RemoveTearoff(&InternalAList());
79 void DOMSVGAnimatedNumberList::InternalBaseValListWillChangeTo(
80 const SVGNumberList
& aNewValue
) {
81 // When the number of items in our internal counterpart's baseVal changes,
82 // we MUST keep our baseVal in sync. If we don't, script will either see a
83 // list that is too short and be unable to access indexes that should be
84 // valid, or else, MUCH WORSE, script will see a list that is too long and be
85 // able to access "items" at indexes that are out of bounds (read/write to
88 RefPtr
<DOMSVGAnimatedNumberList
> kungFuDeathGrip
;
90 if (aNewValue
.Length() < mBaseVal
->LengthNoFlush()) {
91 // InternalListLengthWillChange might clear last reference to |this|.
92 // Retain a temporary reference to keep from dying before returning.
93 kungFuDeathGrip
= this;
95 mBaseVal
->InternalListLengthWillChange(aNewValue
.Length());
98 // If our attribute is not animating, then our animVal mirrors our baseVal
99 // and we must sync its length too. (If our attribute is animating, then the
100 // SMIL engine takes care of calling InternalAnimValListWillChangeTo() if
103 if (!IsAnimating()) {
104 InternalAnimValListWillChangeTo(aNewValue
);
108 void DOMSVGAnimatedNumberList::InternalAnimValListWillChangeTo(
109 const SVGNumberList
& aNewValue
) {
111 mAnimVal
->InternalListLengthWillChange(aNewValue
.Length());
115 bool DOMSVGAnimatedNumberList::IsAnimating() const {
116 return InternalAList().IsAnimating();
119 SVGAnimatedNumberList
& DOMSVGAnimatedNumberList::InternalAList() {
120 return *mElement
->GetAnimatedNumberList(mAttrEnum
);
123 const SVGAnimatedNumberList
& DOMSVGAnimatedNumberList::InternalAList() const {
124 return *mElement
->GetAnimatedNumberList(mAttrEnum
);
127 } // namespace mozilla::dom