Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/svg/DOMSVGTransformList.h
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
#ifndef MOZILLA_DOMSVGTRANSFORMLIST_H__
8
#define MOZILLA_DOMSVGTRANSFORMLIST_H__
9
10
#include "mozilla/dom/SVGAnimatedTransformList.h"
11
#include "nsCycleCollectionParticipant.h"
12
#include "nsDebug.h"
13
#include "nsTArray.h"
14
#include "SVGTransformList.h"
15
#include "mozilla/Attributes.h"
16
#include "mozilla/ErrorResult.h"
17
18
class nsSVGElement;
19
20
namespace mozilla {
21
22
namespace dom {
23
class SVGMatrix;
24
class SVGTransform;
25
} // namespace dom
26
27
/**
28
 * Class DOMSVGTransformList
29
 *
30
 * This class is used to create the DOM tearoff objects that wrap internal
31
 * SVGTransformList objects.
32
 *
33
 * See the architecture comment in SVGAnimatedTransformList.h.
34
 */
35
class DOMSVGTransformList final : public nsISupports,
36
                                  public nsWrapperCache
37
{
38
  friend class AutoChangeTransformListNotifier;
39
  friend class dom::SVGTransform;
40
41
0
  ~DOMSVGTransformList() {
42
0
    // Our mAList's weak ref to us must be nulled out when we die. If GC has
43
0
    // unlinked us using the cycle collector code, then that has already
44
0
    // happened, and mAList is null.
45
0
    if (mAList) {
46
0
      ( IsAnimValList() ? mAList->mAnimVal : mAList->mBaseVal ) = nullptr;
47
0
    }
48
0
  }
49
50
public:
51
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
52
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGTransformList)
53
54
  DOMSVGTransformList(dom::SVGAnimatedTransformList *aAList,
55
                      const SVGTransformList &aInternalList)
56
    : mAList(aAList)
57
0
  {
58
0
    // aInternalList must be passed in explicitly because we can't use
59
0
    // InternalList() here. (Because it depends on IsAnimValList, which depends
60
0
    // on this object having been assigned to aAList's mBaseVal or mAnimVal,
61
0
    // which hasn't happened yet.)
62
0
63
0
    InternalListLengthWillChange(aInternalList.Length()); // Sync mItems
64
0
  }
65
66
  virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
67
68
  nsISupports* GetParentObject()
69
0
  {
70
0
    return static_cast<nsIContent*>(Element());
71
0
  }
72
73
  /**
74
   * This will normally be the same as InternalList().Length(), except if we've
75
   * hit OOM in which case our length will be zero.
76
   */
77
0
  uint32_t LengthNoFlush() const {
78
0
    MOZ_ASSERT(mItems.IsEmpty() || mItems.Length() == InternalList().Length(),
79
0
               "DOM wrapper's list length is out of sync");
80
0
    return mItems.Length();
81
0
  }
82
83
  /// Called to notify us to synchronize our length and detach excess items.
84
  void InternalListLengthWillChange(uint32_t aNewLength);
85
86
  /**
87
   * Returns true if our attribute is animating (in which case our animVal is
88
   * not simply a mirror of our baseVal).
89
   */
90
0
  bool IsAnimating() const {
91
0
    return mAList->IsAnimating();
92
0
  }
93
  /**
94
   * Returns true if there is an animated list mirroring the base list.
95
   */
96
0
  bool AnimListMirrorsBaseList() const {
97
0
    return mAList->mAnimVal && !mAList->IsAnimating();
98
0
  }
99
100
  uint32_t NumberOfItems() const
101
0
  {
102
0
    if (IsAnimValList()) {
103
0
      Element()->FlushAnimations();
104
0
    }
105
0
    return LengthNoFlush();
106
0
  }
107
  void Clear(ErrorResult& error);
108
  already_AddRefed<dom::SVGTransform> Initialize(dom::SVGTransform& newItem,
109
                                                 ErrorResult& error);
110
  already_AddRefed<dom::SVGTransform> GetItem(uint32_t index,
111
                                              ErrorResult& error);
112
  already_AddRefed<dom::SVGTransform> IndexedGetter(uint32_t index, bool& found,
113
                                                    ErrorResult& error);
114
  already_AddRefed<dom::SVGTransform> InsertItemBefore(dom::SVGTransform& newItem,
115
                                                       uint32_t index,
116
                                                       ErrorResult& error);
117
  already_AddRefed<dom::SVGTransform> ReplaceItem(dom::SVGTransform& newItem,
118
                                                  uint32_t index,
119
                                                  ErrorResult& error);
120
  already_AddRefed<dom::SVGTransform> RemoveItem(uint32_t index,
121
                                                 ErrorResult& error);
122
  already_AddRefed<dom::SVGTransform> AppendItem(dom::SVGTransform& newItem,
123
                                                 ErrorResult& error)
124
0
  {
125
0
    return InsertItemBefore(newItem, LengthNoFlush(), error);
126
0
  }
127
  already_AddRefed<dom::SVGTransform> CreateSVGTransformFromMatrix(dom::SVGMatrix& matrix);
128
  already_AddRefed<dom::SVGTransform> Consolidate(ErrorResult& error);
129
  uint32_t Length() const
130
0
  {
131
0
    return NumberOfItems();
132
0
  }
133
134
private:
135
136
0
  nsSVGElement* Element() const {
137
0
    return mAList->mElement;
138
0
  }
139
140
  /// Used to determine if this list is the baseVal or animVal list.
141
0
  bool IsAnimValList() const {
142
0
    MOZ_ASSERT(this == mAList->mBaseVal || this == mAList->mAnimVal,
143
0
               "Calling IsAnimValList() too early?!");
144
0
    return this == mAList->mAnimVal;
145
0
  }
146
147
  /**
148
   * Get a reference to this object's corresponding internal SVGTransformList.
149
   *
150
   * To simplify the code we just have this one method for obtaining both
151
   * baseVal and animVal internal lists. This means that animVal lists don't
152
   * get const protection, but our setter methods guard against changing
153
   * animVal lists.
154
   */
155
  SVGTransformList& InternalList() const;
156
157
  /// Returns the SVGTransform at aIndex, creating it if necessary.
158
  already_AddRefed<dom::SVGTransform> GetItemAt(uint32_t aIndex);
159
160
  void MaybeInsertNullInAnimValListAt(uint32_t aIndex);
161
  void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex);
162
163
  // Weak refs to our SVGTransform items. The items are friends and take care
164
  // of clearing our pointer to them when they die.
165
  FallibleTArray<dom::SVGTransform*> mItems;
166
167
  RefPtr<dom::SVGAnimatedTransformList> mAList;
168
};
169
170
} // namespace mozilla
171
172
#endif // MOZILLA_DOMSVGTRANSFORMLIST_H__