summaryrefslogtreecommitdiffstats
path: root/dom/svg/SVGAnimatedTransformList.h
blob: 7bef84d2fe65c4cb9e73ac491edfb96e2cc490f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_SVGAnimatedTransformList_h
#define mozilla_dom_SVGAnimatedTransformList_h

#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsSVGElement.h"
#include "nsWrapperCache.h"
#include "mozilla/Attributes.h"

namespace mozilla {

class DOMSVGTransformList;
class nsSVGAnimatedTransformList;

namespace dom {

/**
 * Class SVGAnimatedTransformList
 *
 * This class is used to create the DOM tearoff objects that wrap internal
 * nsSVGAnimatedTransformList objects.
 *
 * See the architecture comment in DOMSVGAnimatedLengthList.h (that's
 * LENGTH list). The comment for that class largly applies to this one too
 * and will go a long way to helping you understand the architecture here.
 *
 * This class is strongly intertwined with DOMSVGTransformList and
 * DOMSVGTransform.
 * Our DOMSVGTransformList base and anim vals are friends and take care of
 * nulling out our pointers to them when they die (making our pointers to them
 * true weak refs).
 */
class SVGAnimatedTransformList final : public nsWrapperCache
{
  friend class mozilla::DOMSVGTransformList;

public:
  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(SVGAnimatedTransformList)
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(SVGAnimatedTransformList)

  /**
   * Factory method to create and return a SVGAnimatedTransformList wrapper
   * for a given internal nsSVGAnimatedTransformList object. The factory takes
   * care of caching the object that it returns so that the same object can be
   * returned for the given nsSVGAnimatedTransformList each time it is requested.
   * The cached object is only removed from the cache when it is destroyed due
   * to there being no more references to it or to any of its descendant
   * objects. If that happens, any subsequent call requesting the DOM wrapper
   * for the nsSVGAnimatedTransformList will naturally result in a new
   * SVGAnimatedTransformList being returned.
   */
  static already_AddRefed<SVGAnimatedTransformList>
    GetDOMWrapper(nsSVGAnimatedTransformList *aList, nsSVGElement *aElement);

  /**
   * This method returns the SVGAnimatedTransformList wrapper for an internal
   * nsSVGAnimatedTransformList object if it currently has a wrapper. If it does
   * not, then nullptr is returned.
   */
  static SVGAnimatedTransformList*
    GetDOMWrapperIfExists(nsSVGAnimatedTransformList *aList);

  /**
   * Called by internal code to notify us when we need to sync the length of
   * our baseVal DOM list with its internal list. This is called just prior to
   * the length of the internal baseVal list being changed so that any DOM list
   * items that need to be removed from the DOM list can first get their values
   * from their internal counterpart.
   *
   * The only time this method could fail is on OOM when trying to increase the
   * length of the DOM list. If that happens then this method simply clears the
   * list and returns. Callers just proceed as normal, and we simply accept
   * that the DOM list will be empty (until successfully set to a new value).
   */
  void InternalBaseValListWillChangeLengthTo(uint32_t aNewLength);
  void InternalAnimValListWillChangeLengthTo(uint32_t aNewLength);

  /**
   * Returns true if our attribute is animating (in which case our animVal is
   * not simply a mirror of our baseVal).
   */
  bool IsAnimating() const;

  // WebIDL
  nsSVGElement* GetParentObject() const { return mElement; }
  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
  // These aren't weak refs because mBaseVal and mAnimVal are weak
  already_AddRefed<DOMSVGTransformList> BaseVal();
  already_AddRefed<DOMSVGTransformList> AnimVal();

private:

  /**
   * Only our static GetDOMWrapper() factory method may create objects of our
   * type.
   */
  explicit SVGAnimatedTransformList(nsSVGElement *aElement)
    : mBaseVal(nullptr)
    , mAnimVal(nullptr)
    , mElement(aElement)
  {
  }

  ~SVGAnimatedTransformList();

  /// Get a reference to this DOM wrapper object's internal counterpart.
  nsSVGAnimatedTransformList& InternalAList();
  const nsSVGAnimatedTransformList& InternalAList() const;

  // Weak refs to our DOMSVGTransformList baseVal/animVal objects. These objects
  // are friends and take care of clearing these pointers when they die, making
  // these true weak references.
  DOMSVGTransformList *mBaseVal;
  DOMSVGTransformList *mAnimVal;

  // Strong ref to our element to keep it alive. We hold this not only for
  // ourself, but also for our base/animVal and all of their items.
  RefPtr<nsSVGElement> mElement;
};

} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_SVGAnimatedTransformList_h