DOMSVGTransformList.h 5.8 KB

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