Line data Source code
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 "mozilla/dom/SVGAnimatedTransformList.h"
8 : #include "DOMSVGTransformList.h"
9 : #include "nsSVGAnimatedTransformList.h"
10 : #include "nsSVGAttrTearoffTable.h"
11 : #include "mozilla/dom/SVGAnimatedTransformListBinding.h"
12 :
13 : namespace mozilla {
14 : namespace dom {
15 :
16 : static
17 : nsSVGAttrTearoffTable<nsSVGAnimatedTransformList, SVGAnimatedTransformList>
18 3 : sSVGAnimatedTransformListTearoffTable;
19 :
20 0 : NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(SVGAnimatedTransformList, mElement)
21 :
22 0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(SVGAnimatedTransformList, AddRef)
23 0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(SVGAnimatedTransformList, Release)
24 :
25 : JSObject*
26 0 : SVGAnimatedTransformList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
27 : {
28 0 : return SVGAnimatedTransformListBinding::Wrap(aCx, this, aGivenProto);
29 : }
30 :
31 : //----------------------------------------------------------------------
32 : already_AddRefed<DOMSVGTransformList>
33 0 : SVGAnimatedTransformList::BaseVal()
34 : {
35 0 : if (!mBaseVal) {
36 0 : mBaseVal = new DOMSVGTransformList(this, InternalAList().GetBaseValue());
37 : }
38 0 : RefPtr<DOMSVGTransformList> baseVal = mBaseVal;
39 0 : return baseVal.forget();
40 : }
41 :
42 : already_AddRefed<DOMSVGTransformList>
43 0 : SVGAnimatedTransformList::AnimVal()
44 : {
45 0 : if (!mAnimVal) {
46 0 : mAnimVal = new DOMSVGTransformList(this, InternalAList().GetAnimValue());
47 : }
48 0 : RefPtr<DOMSVGTransformList> animVal = mAnimVal;
49 0 : return animVal.forget();
50 : }
51 :
52 : /* static */ already_AddRefed<SVGAnimatedTransformList>
53 0 : SVGAnimatedTransformList::GetDOMWrapper(nsSVGAnimatedTransformList *aList,
54 : nsSVGElement *aElement)
55 : {
56 : RefPtr<SVGAnimatedTransformList> wrapper =
57 0 : sSVGAnimatedTransformListTearoffTable.GetTearoff(aList);
58 0 : if (!wrapper) {
59 0 : wrapper = new SVGAnimatedTransformList(aElement);
60 0 : sSVGAnimatedTransformListTearoffTable.AddTearoff(aList, wrapper);
61 : }
62 0 : return wrapper.forget();
63 : }
64 :
65 : /* static */ SVGAnimatedTransformList*
66 7 : SVGAnimatedTransformList::GetDOMWrapperIfExists(
67 : nsSVGAnimatedTransformList *aList)
68 : {
69 7 : return sSVGAnimatedTransformListTearoffTable.GetTearoff(aList);
70 : }
71 :
72 0 : SVGAnimatedTransformList::~SVGAnimatedTransformList()
73 : {
74 : // Script no longer has any references to us, to our base/animVal objects, or
75 : // to any of their list items.
76 0 : sSVGAnimatedTransformListTearoffTable.RemoveTearoff(&InternalAList());
77 0 : }
78 :
79 : void
80 0 : SVGAnimatedTransformList::InternalBaseValListWillChangeLengthTo(
81 : uint32_t aNewLength)
82 : {
83 : // When the number of items in our internal counterpart's baseVal changes,
84 : // we MUST keep our baseVal in sync. If we don't, script will either see a
85 : // list that is too short and be unable to access indexes that should be
86 : // valid, or else, MUCH WORSE, script will see a list that is too long and be
87 : // able to access "items" at indexes that are out of bounds (read/write to
88 : // bad memory)!!
89 :
90 0 : RefPtr<SVGAnimatedTransformList> kungFuDeathGrip;
91 0 : if (mBaseVal) {
92 0 : if (aNewLength < mBaseVal->LengthNoFlush()) {
93 : // InternalListLengthWillChange might clear last reference to |this|.
94 : // Retain a temporary reference to keep from dying before returning.
95 0 : kungFuDeathGrip = this;
96 : }
97 0 : mBaseVal->InternalListLengthWillChange(aNewLength);
98 : }
99 :
100 : // If our attribute is not animating, then our animVal mirrors our baseVal
101 : // and we must sync its length too. (If our attribute is animating, then the
102 : // SMIL engine takes care of calling InternalAnimValListWillChangeLengthTo()
103 : // if necessary.)
104 :
105 0 : if (!IsAnimating()) {
106 0 : InternalAnimValListWillChangeLengthTo(aNewLength);
107 : }
108 0 : }
109 :
110 : void
111 0 : SVGAnimatedTransformList::InternalAnimValListWillChangeLengthTo(
112 : uint32_t aNewLength)
113 : {
114 0 : if (mAnimVal) {
115 0 : mAnimVal->InternalListLengthWillChange(aNewLength);
116 : }
117 0 : }
118 :
119 : bool
120 0 : SVGAnimatedTransformList::IsAnimating() const
121 : {
122 0 : return InternalAList().IsAnimating();
123 : }
124 :
125 : nsSVGAnimatedTransformList&
126 0 : SVGAnimatedTransformList::InternalAList()
127 : {
128 0 : return *mElement->GetAnimatedTransformList();
129 : }
130 :
131 : const nsSVGAnimatedTransformList&
132 0 : SVGAnimatedTransformList::InternalAList() const
133 : {
134 0 : return *mElement->GetAnimatedTransformList();
135 : }
136 :
137 : } // namespace dom
138 : } // namespace mozilla
|