|
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 /* |
|
8 * nsINodeInfo is an interface to node info, such as name, prefix, namespace |
|
9 * ID and possibly other data that is shared between nodes (elements |
|
10 * and attributes) that have the same name, prefix and namespace ID within |
|
11 * the same document. |
|
12 * |
|
13 * nsNodeInfoManager's are internal objects that manage a list of |
|
14 * nsINodeInfo's, every document object should hold a strong reference to |
|
15 * a nsNodeInfoManager and every nsINodeInfo also holds a strong reference |
|
16 * to their owning manager. When a nsINodeInfo is no longer used it will |
|
17 * automatically remove itself from its owner manager, and when all |
|
18 * nsINodeInfo's have been removed from a nsNodeInfoManager and all external |
|
19 * references are released the nsNodeInfoManager deletes itself. |
|
20 * |
|
21 * -- jst@netscape.com |
|
22 */ |
|
23 |
|
24 #ifndef nsINodeInfo_h___ |
|
25 #define nsINodeInfo_h___ |
|
26 |
|
27 #include "nsCOMPtr.h" // for member |
|
28 #include "nsIAtom.h" // for member (in nsCOMPtr) |
|
29 #include "nsISupports.h" // for base class |
|
30 #include "nsNameSpaceManager.h" // for kNameSpaceID_* |
|
31 |
|
32 #ifdef MOZILLA_INTERNAL_API |
|
33 #include "nsDOMString.h" |
|
34 #endif |
|
35 |
|
36 class nsIDocument; |
|
37 class nsIURI; |
|
38 class nsIPrincipal; |
|
39 class nsNodeInfoManager; |
|
40 |
|
41 // IID for the nsINodeInfo interface |
|
42 #define NS_INODEINFO_IID \ |
|
43 { 0xc5188ea1, 0x0a9c, 0x43e6, \ |
|
44 { 0x95, 0x90, 0xcc, 0x43, 0x6b, 0xe9, 0xcf, 0xa0 } } |
|
45 |
|
46 class nsINodeInfo : public nsISupports |
|
47 { |
|
48 public: |
|
49 NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEINFO_IID) |
|
50 |
|
51 nsINodeInfo() |
|
52 : mInner(nullptr, nullptr, kNameSpaceID_None, 0, nullptr) |
|
53 { |
|
54 } |
|
55 |
|
56 /* |
|
57 * Get the name from this node as a string, this does not include the prefix. |
|
58 * |
|
59 * For the HTML element "<body>" this will return "body" and for the XML |
|
60 * element "<html:body>" this will return "body". |
|
61 */ |
|
62 void GetName(nsAString& aName) const |
|
63 { |
|
64 mInner.mName->ToString(aName); |
|
65 } |
|
66 |
|
67 /* |
|
68 * Get the name from this node as an atom, this does not include the prefix. |
|
69 * This function never returns a null atom. |
|
70 * |
|
71 * For the HTML element "<body>" this will return the "body" atom and for |
|
72 * the XML element "<html:body>" this will return the "body" atom. |
|
73 */ |
|
74 nsIAtom* NameAtom() const |
|
75 { |
|
76 return mInner.mName; |
|
77 } |
|
78 |
|
79 /* |
|
80 * Get the qualified name from this node as a string, the qualified name |
|
81 * includes the prefix, if one exists. |
|
82 * |
|
83 * For the HTML element "<body>" this will return "body" and for the XML |
|
84 * element "<html:body>" this will return "html:body". |
|
85 */ |
|
86 const nsString& QualifiedName() const { |
|
87 return mQualifiedName; |
|
88 } |
|
89 |
|
90 /* |
|
91 * Returns the node's nodeName as defined in DOM Core |
|
92 */ |
|
93 const nsString& NodeName() const { |
|
94 return mNodeName; |
|
95 } |
|
96 |
|
97 /* |
|
98 * Returns the node's localName as defined in DOM Core |
|
99 */ |
|
100 const nsString& LocalName() const { |
|
101 return mLocalName; |
|
102 } |
|
103 |
|
104 #ifdef MOZILLA_INTERNAL_API |
|
105 /* |
|
106 * Get the prefix from this node as a string. |
|
107 * |
|
108 * For the HTML element "<body>" this will return a null string and for |
|
109 * the XML element "<html:body>" this will return the string "html". |
|
110 */ |
|
111 void GetPrefix(nsAString& aPrefix) const |
|
112 { |
|
113 if (mInner.mPrefix) { |
|
114 mInner.mPrefix->ToString(aPrefix); |
|
115 } else { |
|
116 SetDOMStringToNull(aPrefix); |
|
117 } |
|
118 } |
|
119 #endif |
|
120 |
|
121 /* |
|
122 * Get the prefix from this node as an atom. |
|
123 * |
|
124 * For the HTML element "<body>" this will return a null atom and for |
|
125 * the XML element "<html:body>" this will return the "html" atom. |
|
126 */ |
|
127 nsIAtom* GetPrefixAtom() const |
|
128 { |
|
129 return mInner.mPrefix; |
|
130 } |
|
131 |
|
132 /* |
|
133 * Get the namespace URI for a node, if the node has a namespace URI. |
|
134 */ |
|
135 virtual void GetNamespaceURI(nsAString& aNameSpaceURI) const = 0; |
|
136 |
|
137 /* |
|
138 * Get the namespace ID for a node if the node has a namespace, if not this |
|
139 * returns kNameSpaceID_None. |
|
140 */ |
|
141 int32_t NamespaceID() const |
|
142 { |
|
143 return mInner.mNamespaceID; |
|
144 } |
|
145 |
|
146 /* |
|
147 * Get the nodetype for the node. Returns the values specified in nsIDOMNode |
|
148 * for nsIDOMNode.nodeType |
|
149 */ |
|
150 uint16_t NodeType() const |
|
151 { |
|
152 return mInner.mNodeType; |
|
153 } |
|
154 |
|
155 /* |
|
156 * Get the extra name, used by PIs and DocTypes, for the node. |
|
157 */ |
|
158 nsIAtom* GetExtraName() const |
|
159 { |
|
160 return mInner.mExtraName; |
|
161 } |
|
162 |
|
163 /* |
|
164 * Get and set the ID attribute atom for this node. |
|
165 * See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types |
|
166 * for the definition of an ID attribute. |
|
167 * |
|
168 */ |
|
169 nsIAtom* GetIDAttributeAtom() const |
|
170 { |
|
171 return mIDAttributeAtom; |
|
172 } |
|
173 |
|
174 void SetIDAttributeAtom(nsIAtom* aID) |
|
175 { |
|
176 mIDAttributeAtom = aID; |
|
177 } |
|
178 |
|
179 /** |
|
180 * Get the owning node info manager. Only to be used inside Gecko, you can't |
|
181 * really do anything with the pointer outside Gecko anyway. |
|
182 */ |
|
183 nsNodeInfoManager *NodeInfoManager() const |
|
184 { |
|
185 return mOwnerManager; |
|
186 } |
|
187 |
|
188 /* |
|
189 * Utility functions that can be used to check if a nodeinfo holds a specific |
|
190 * name, name and prefix, name and prefix and namespace ID, or just |
|
191 * namespace ID. |
|
192 */ |
|
193 bool Equals(nsINodeInfo *aNodeInfo) const |
|
194 { |
|
195 return aNodeInfo == this || aNodeInfo->Equals(mInner.mName, mInner.mPrefix, |
|
196 mInner.mNamespaceID); |
|
197 } |
|
198 |
|
199 bool NameAndNamespaceEquals(nsINodeInfo *aNodeInfo) const |
|
200 { |
|
201 return aNodeInfo == this || aNodeInfo->Equals(mInner.mName, |
|
202 mInner.mNamespaceID); |
|
203 } |
|
204 |
|
205 bool Equals(nsIAtom *aNameAtom) const |
|
206 { |
|
207 return mInner.mName == aNameAtom; |
|
208 } |
|
209 |
|
210 bool Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom) const |
|
211 { |
|
212 return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom); |
|
213 } |
|
214 |
|
215 bool Equals(nsIAtom *aNameAtom, int32_t aNamespaceID) const |
|
216 { |
|
217 return ((mInner.mName == aNameAtom) && |
|
218 (mInner.mNamespaceID == aNamespaceID)); |
|
219 } |
|
220 |
|
221 bool Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom, |
|
222 int32_t aNamespaceID) const |
|
223 { |
|
224 return ((mInner.mName == aNameAtom) && |
|
225 (mInner.mPrefix == aPrefixAtom) && |
|
226 (mInner.mNamespaceID == aNamespaceID)); |
|
227 } |
|
228 |
|
229 bool NamespaceEquals(int32_t aNamespaceID) const |
|
230 { |
|
231 return mInner.mNamespaceID == aNamespaceID; |
|
232 } |
|
233 |
|
234 bool Equals(const nsAString& aName) const |
|
235 { |
|
236 return mInner.mName->Equals(aName); |
|
237 } |
|
238 |
|
239 bool Equals(const nsAString& aName, const nsAString& aPrefix) const |
|
240 { |
|
241 return mInner.mName->Equals(aName) && |
|
242 (mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) : aPrefix.IsEmpty()); |
|
243 } |
|
244 |
|
245 bool Equals(const nsAString& aName, int32_t aNamespaceID) const |
|
246 { |
|
247 return mInner.mNamespaceID == aNamespaceID && |
|
248 mInner.mName->Equals(aName); |
|
249 } |
|
250 |
|
251 bool Equals(const nsAString& aName, const nsAString& aPrefix, |
|
252 int32_t aNamespaceID) const |
|
253 { |
|
254 return mInner.mName->Equals(aName) && mInner.mNamespaceID == aNamespaceID && |
|
255 (mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) : aPrefix.IsEmpty()); |
|
256 } |
|
257 |
|
258 virtual bool NamespaceEquals(const nsAString& aNamespaceURI) const = 0; |
|
259 |
|
260 bool QualifiedNameEquals(nsIAtom* aNameAtom) const |
|
261 { |
|
262 NS_PRECONDITION(aNameAtom, "Must have name atom"); |
|
263 if (!GetPrefixAtom()) |
|
264 return Equals(aNameAtom); |
|
265 |
|
266 return aNameAtom->Equals(mQualifiedName); |
|
267 } |
|
268 |
|
269 bool QualifiedNameEquals(const nsAString& aQualifiedName) const |
|
270 { |
|
271 return mQualifiedName == aQualifiedName; |
|
272 } |
|
273 |
|
274 /* |
|
275 * Retrieve a pointer to the document that owns this node info. |
|
276 */ |
|
277 nsIDocument* GetDocument() const |
|
278 { |
|
279 return mDocument; |
|
280 } |
|
281 |
|
282 protected: |
|
283 /* |
|
284 * nsNodeInfoInner is used for two things: |
|
285 * |
|
286 * 1. as a member in nsNodeInfo for holding the name, prefix and |
|
287 * namespace ID |
|
288 * 2. as the hash key in the hash table in nsNodeInfoManager |
|
289 * |
|
290 * nsNodeInfoInner does not do any kind of reference counting, |
|
291 * that's up to the user of this class. Since nsNodeInfoInner is |
|
292 * typically used as a member of nsNodeInfo, the hash table doesn't |
|
293 * need to delete the keys. When the value (nsNodeInfo) is deleted |
|
294 * the key is automatically deleted. |
|
295 */ |
|
296 |
|
297 class nsNodeInfoInner |
|
298 { |
|
299 public: |
|
300 nsNodeInfoInner() |
|
301 : mName(nullptr), mPrefix(nullptr), mNamespaceID(kNameSpaceID_Unknown), |
|
302 mNodeType(0), mNameString(nullptr), mExtraName(nullptr) |
|
303 { |
|
304 } |
|
305 nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID, |
|
306 uint16_t aNodeType, nsIAtom* aExtraName) |
|
307 : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID), |
|
308 mNodeType(aNodeType), mNameString(nullptr), mExtraName(aExtraName) |
|
309 { |
|
310 } |
|
311 nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix, |
|
312 int32_t aNamespaceID, uint16_t aNodeType) |
|
313 : mName(nullptr), mPrefix(aPrefix), mNamespaceID(aNamespaceID), |
|
314 mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nullptr) |
|
315 { |
|
316 } |
|
317 |
|
318 nsIAtom* mName; |
|
319 nsIAtom* mPrefix; |
|
320 int32_t mNamespaceID; |
|
321 uint16_t mNodeType; // As defined by nsIDOMNode.nodeType |
|
322 const nsAString* mNameString; |
|
323 nsIAtom* mExtraName; // Only used by PIs and DocTypes |
|
324 }; |
|
325 |
|
326 // nsNodeInfoManager needs to pass mInner to the hash table. |
|
327 friend class nsNodeInfoManager; |
|
328 |
|
329 nsIDocument* mDocument; // Weak. Cache of mOwnerManager->mDocument |
|
330 |
|
331 nsNodeInfoInner mInner; |
|
332 |
|
333 nsCOMPtr<nsIAtom> mIDAttributeAtom; |
|
334 nsRefPtr<nsNodeInfoManager> mOwnerManager; |
|
335 |
|
336 /* |
|
337 * Members for various functions of mName+mPrefix that we can be |
|
338 * asked to compute. |
|
339 */ |
|
340 |
|
341 // Qualified name |
|
342 nsString mQualifiedName; |
|
343 |
|
344 // nodeName for the node. |
|
345 nsString mNodeName; |
|
346 |
|
347 // localName for the node. This is either equal to mInner.mName, or a |
|
348 // void string, depending on mInner.mNodeType. |
|
349 nsString mLocalName; |
|
350 }; |
|
351 |
|
352 NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeInfo, NS_INODEINFO_IID) |
|
353 |
|
354 #endif /* nsINodeInfo_h___ */ |