Coverage Report

Created: 2018-09-25 14:53

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