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 : #ifndef MOZILLA_DOMSVGNUMBER_H__
8 : #define MOZILLA_DOMSVGNUMBER_H__
9 :
10 : #include "DOMSVGNumberList.h"
11 : #include "nsCycleCollectionParticipant.h"
12 : #include "nsTArray.h"
13 : #include "mozilla/Attributes.h"
14 : #include "mozilla/ErrorResult.h"
15 : #include "nsWrapperCache.h"
16 :
17 : class nsSVGElement;
18 :
19 : #define MOZ_SVG_LIST_INDEX_BIT_COUNT 27 // supports > 134 million list items
20 :
21 : namespace mozilla {
22 :
23 : /**
24 : * Class DOMSVGNumber
25 : *
26 : * This class creates the DOM objects that wrap internal SVGNumber objects that
27 : * are in an SVGNumberList. It is also used to create the objects returned by
28 : * SVGSVGElement.createSVGNumber().
29 : *
30 : * For the DOM wrapper classes for non-list SVGNumber, see nsSVGNumber2.h.
31 : *
32 : * See the architecture comment in DOMSVGAnimatedNumberList.h.
33 : *
34 : * See the comment in DOMSVGLength.h (yes, LENGTH), which applies here too.
35 : */
36 : class DOMSVGNumber final : public nsISupports
37 : , public nsWrapperCache
38 : {
39 : friend class AutoChangeNumberNotifier;
40 :
41 0 : ~DOMSVGNumber() {
42 : // Our mList's weak ref to us must be nulled out when we die. If GC has
43 : // unlinked us using the cycle collector code, then that has already
44 : // happened, and mList is null.
45 0 : if (mList) {
46 0 : mList->mItems[mListIndex] = nullptr;
47 : }
48 0 : }
49 :
50 : public:
51 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
52 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGNumber)
53 :
54 : /**
55 : * Generic ctor for DOMSVGNumber objects that are created for an attribute.
56 : */
57 : DOMSVGNumber(DOMSVGNumberList *aList,
58 : uint8_t aAttrEnum,
59 : uint32_t aListIndex,
60 : bool aIsAnimValItem);
61 :
62 : /**
63 : * Ctor for creating the objects returned by SVGSVGElement.createSVGNumber(),
64 : * which do not initially belong to an attribute.
65 : */
66 : explicit DOMSVGNumber(nsISupports* aParent);
67 :
68 : /**
69 : * Create an unowned copy. The caller is responsible for the first AddRef().
70 : */
71 0 : DOMSVGNumber* Clone() {
72 0 : DOMSVGNumber *clone = new DOMSVGNumber(mParent);
73 0 : clone->mValue = ToSVGNumber();
74 0 : return clone;
75 : }
76 :
77 : bool IsInList() const {
78 : return !!mList;
79 : }
80 :
81 : /**
82 : * In future, if this class is used for non-list numbers, this will be
83 : * different to IsInList().
84 : */
85 0 : bool HasOwner() const {
86 0 : return !!mList;
87 : }
88 :
89 : /**
90 : * This method is called to notify this DOM object that it is being inserted
91 : * into a list, and give it the information it needs as a result.
92 : *
93 : * This object MUST NOT already belong to a list when this method is called.
94 : * That's not to say that script can't move these DOM objects between
95 : * lists - it can - it's just that the logic to handle that (and send out
96 : * the necessary notifications) is located elsewhere (in DOMSVGNumberList).)
97 : */
98 : void InsertingIntoList(DOMSVGNumberList *aList,
99 : uint8_t aAttrEnum,
100 : uint32_t aListIndex,
101 : bool aIsAnimValItem);
102 :
103 0 : static uint32_t MaxListIndex() {
104 0 : return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
105 : }
106 :
107 : /// This method is called to notify this object that its list index changed.
108 0 : void UpdateListIndex(uint32_t aListIndex) {
109 0 : mListIndex = aListIndex;
110 0 : }
111 :
112 : /**
113 : * This method is called to notify this DOM object that it is about to be
114 : * removed from its current DOM list so that it can first make a copy of its
115 : * internal counterpart's value. (If it didn't do this, then it would
116 : * "lose" its value on being removed.)
117 : */
118 : void RemovingFromList();
119 :
120 : float ToSVGNumber();
121 :
122 0 : nsISupports* GetParentObject()
123 : {
124 0 : return mParent;
125 : }
126 :
127 : virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
128 :
129 : static already_AddRefed<DOMSVGNumber>
130 : Constructor(const dom::GlobalObject& aGlobal, ErrorResult& aRv);
131 :
132 : static already_AddRefed<DOMSVGNumber>
133 : Constructor(const dom::GlobalObject& aGlobal, float aValue, ErrorResult& aRv);
134 :
135 : float Value();
136 :
137 : void SetValue(float aValue, ErrorResult& aRv);
138 :
139 : private:
140 :
141 0 : nsSVGElement* Element() {
142 0 : return mList->Element();
143 : }
144 :
145 : uint8_t AttrEnum() const {
146 : return mAttrEnum;
147 : }
148 :
149 : /**
150 : * Get a reference to the internal SVGNumber list item that this DOM wrapper
151 : * object currently wraps.
152 : *
153 : * To simplify the code we just have this one method for obtaining both
154 : * baseVal and animVal internal items. This means that animVal items don't
155 : * get const protection, but then our setter methods guard against changing
156 : * animVal items.
157 : */
158 : float& InternalItem();
159 :
160 : #ifdef DEBUG
161 : bool IndexIsValid();
162 : #endif
163 :
164 : RefPtr<DOMSVGNumberList> mList;
165 : nsCOMPtr<nsISupports> mParent;
166 :
167 : // Bounds for the following are checked in the ctor, so be sure to update
168 : // that if you change the capacity of any of the following.
169 :
170 : uint32_t mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
171 : uint32_t mAttrEnum:4; // supports up to 16 attributes
172 : uint32_t mIsAnimValItem:1;
173 :
174 : // The following member is only used when we're not in a list:
175 : float mValue;
176 : };
177 :
178 : } // namespace mozilla
179 :
180 : #undef MOZ_SVG_LIST_INDEX_BIT_COUNT
181 :
182 : #endif // MOZILLA_DOMSVGNUMBER_H__
|