Merge mozilla-central to autoland on a CLOSED TREE
[gecko.git] / dom / svg / DOMSVGAnimatedNumberList.cpp
blobd0fac03f4d709a3c1319994b8f8749ed3559eaf2
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,
29 mElement)
31 JSObject* DOMSVGAnimatedNumberList::WrapObject(
32 JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
33 return mozilla::dom::SVGAnimatedNumberList_Binding::Wrap(aCx, this,
34 aGivenProto);
37 already_AddRefed<DOMSVGNumberList> DOMSVGAnimatedNumberList::BaseVal() {
38 if (!mBaseVal) {
39 mBaseVal = new DOMSVGNumberList(this, InternalAList().GetBaseValue());
41 RefPtr<DOMSVGNumberList> baseVal = mBaseVal;
42 return baseVal.forget();
45 already_AddRefed<DOMSVGNumberList> DOMSVGAnimatedNumberList::AnimVal() {
46 if (!mAnimVal) {
47 mAnimVal = new DOMSVGNumberList(this, InternalAList().GetAnimValue());
49 RefPtr<DOMSVGNumberList> animVal = mAnimVal;
50 return animVal.forget();
53 /* static */
54 already_AddRefed<DOMSVGAnimatedNumberList>
55 DOMSVGAnimatedNumberList::GetDOMWrapper(SVGAnimatedNumberList* aList,
56 dom::SVGElement* aElement,
57 uint8_t aAttrEnum) {
58 RefPtr<DOMSVGAnimatedNumberList> wrapper =
59 SVGAnimatedNumberListTearoffTable().GetTearoff(aList);
60 if (!wrapper) {
61 wrapper = new DOMSVGAnimatedNumberList(aElement, aAttrEnum);
62 SVGAnimatedNumberListTearoffTable().AddTearoff(aList, wrapper);
64 return wrapper.forget();
67 /* static */
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
86 // bad memory)!!
88 RefPtr<DOMSVGAnimatedNumberList> kungFuDeathGrip;
89 if (mBaseVal) {
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
101 // necessary.)
103 if (!IsAnimating()) {
104 InternalAnimValListWillChangeTo(aNewValue);
108 void DOMSVGAnimatedNumberList::InternalAnimValListWillChangeTo(
109 const SVGNumberList& aNewValue) {
110 if (mAnimVal) {
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