1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /*
39 : * nsINodeInfo is an interface to node info, such as name, prefix, namespace
40 : * ID and possibly other data that is shared between nodes (elements
41 : * and attributes) that have the same name, prefix and namespace ID within
42 : * the same document.
43 : *
44 : * nsNodeInfoManager's are internal objects that manage a list of
45 : * nsINodeInfo's, every document object should hold a strong reference to
46 : * a nsNodeInfoManager and every nsINodeInfo also holds a strong reference
47 : * to their owning manager. When a nsINodeInfo is no longer used it will
48 : * automatically remove itself from its owner manager, and when all
49 : * nsINodeInfo's have been removed from a nsNodeInfoManager and all external
50 : * references are released the nsNodeInfoManager deletes itself.
51 : *
52 : * -- jst@netscape.com
53 : */
54 :
55 : #ifndef nsINodeInfo_h___
56 : #define nsINodeInfo_h___
57 :
58 : #include "nsISupports.h"
59 : #include "nsIAtom.h"
60 : #include "nsINameSpaceManager.h"
61 : #include "nsNodeInfoManager.h"
62 : #include "nsCOMPtr.h"
63 :
64 : #ifdef MOZILLA_INTERNAL_API
65 : #include "nsDOMString.h"
66 : #endif
67 :
68 : // Forward declarations
69 : class nsIDocument;
70 : class nsIURI;
71 : class nsIPrincipal;
72 :
73 : // IID for the nsINodeInfo interface
74 : #define NS_INODEINFO_IID \
75 : { 0xc5188ea1, 0x0a9c, 0x43e6, \
76 : { 0x95, 0x90, 0xcc, 0x43, 0x6b, 0xe9, 0xcf, 0xa0 } }
77 :
78 : class nsINodeInfo : public nsISupports
79 11985 : {
80 : public:
81 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEINFO_IID)
82 :
83 11993 : nsINodeInfo()
84 : : mInner(nsnull, nsnull, kNameSpaceID_None, 0, nsnull),
85 11993 : mOwnerManager(nsnull)
86 : {
87 11993 : }
88 :
89 : /*
90 : * Get the name from this node as a string, this does not include the prefix.
91 : *
92 : * For the HTML element "<body>" this will return "body" and for the XML
93 : * element "<html:body>" this will return "body".
94 : */
95 847 : void GetName(nsAString& aName) const
96 : {
97 847 : mInner.mName->ToString(aName);
98 847 : }
99 :
100 : /*
101 : * Get the name from this node as an atom, this does not include the prefix.
102 : * This function never returns a null atom.
103 : *
104 : * For the HTML element "<body>" this will return the "body" atom and for
105 : * the XML element "<html:body>" this will return the "body" atom.
106 : */
107 33082 : nsIAtom* NameAtom() const
108 : {
109 33082 : return mInner.mName;
110 : }
111 :
112 : /*
113 : * Get the qualified name from this node as a string, the qualified name
114 : * includes the prefix, if one exists.
115 : *
116 : * For the HTML element "<body>" this will return "body" and for the XML
117 : * element "<html:body>" this will return "html:body".
118 : */
119 0 : const nsString& QualifiedName() const {
120 0 : return mQualifiedName;
121 : }
122 :
123 : /*
124 : * Returns the node's nodeName as defined in DOM Core
125 : */
126 5894 : const nsString& NodeName() const {
127 5894 : return mNodeName;
128 : }
129 :
130 : /*
131 : * Returns the node's localName as defined in DOM Core
132 : */
133 8748 : const nsString& LocalName() const {
134 8748 : return mLocalName;
135 : }
136 :
137 : #ifdef MOZILLA_INTERNAL_API
138 : /*
139 : * Get the prefix from this node as a string.
140 : *
141 : * For the HTML element "<body>" this will return a null string and for
142 : * the XML element "<html:body>" this will return the string "html".
143 : */
144 811 : void GetPrefix(nsAString& aPrefix) const
145 : {
146 811 : if (mInner.mPrefix) {
147 92 : mInner.mPrefix->ToString(aPrefix);
148 : } else {
149 719 : SetDOMStringToNull(aPrefix);
150 : }
151 811 : }
152 : #endif
153 :
154 : /*
155 : * Get the prefix from this node as an atom.
156 : *
157 : * For the HTML element "<body>" this will return a null atom and for
158 : * the XML element "<html:body>" this will return the "html" atom.
159 : */
160 35173 : nsIAtom* GetPrefixAtom() const
161 : {
162 35173 : return mInner.mPrefix;
163 : }
164 :
165 : /*
166 : * Get the namespace URI for a node, if the node has a namespace URI.
167 : */
168 : virtual nsresult GetNamespaceURI(nsAString& aNameSpaceURI) const = 0;
169 :
170 : /*
171 : * Get the namespace ID for a node if the node has a namespace, if not this
172 : * returns kNameSpaceID_None.
173 : */
174 790114 : PRInt32 NamespaceID() const
175 : {
176 790114 : return mInner.mNamespaceID;
177 : }
178 :
179 : /*
180 : * Get the nodetype for the node. Returns the values specified in nsIDOMNode
181 : * for nsIDOMNode.nodeType
182 : */
183 1131557 : PRUint16 NodeType() const
184 : {
185 1131557 : return mInner.mNodeType;
186 : }
187 :
188 : /*
189 : * Get the extra name, used by PIs and DocTypes, for the node.
190 : */
191 6838 : nsIAtom* GetExtraName() const
192 : {
193 6838 : return mInner.mExtraName;
194 : }
195 :
196 : /*
197 : * Get and set the ID attribute atom for this node.
198 : * See http://www.w3.org/TR/1998/REC-xml-19980210#sec-attribute-types
199 : * for the definition of an ID attribute.
200 : *
201 : */
202 11593 : nsIAtom* GetIDAttributeAtom() const
203 : {
204 11593 : return mIDAttributeAtom;
205 : }
206 :
207 112 : void SetIDAttributeAtom(nsIAtom* aID)
208 : {
209 112 : mIDAttributeAtom = aID;
210 112 : }
211 :
212 : /**
213 : * Get the owning node info manager. Only to be used inside Gecko, you can't
214 : * really do anything with the pointer outside Gecko anyway.
215 : */
216 455864 : nsNodeInfoManager *NodeInfoManager() const
217 : {
218 455864 : return mOwnerManager;
219 : }
220 :
221 : /*
222 : * Utility functions that can be used to check if a nodeinfo holds a specific
223 : * name, name and prefix, name and prefix and namespace ID, or just
224 : * namespace ID.
225 : */
226 3439 : bool Equals(nsINodeInfo *aNodeInfo) const
227 : {
228 : return aNodeInfo == this || aNodeInfo->Equals(mInner.mName, mInner.mPrefix,
229 3439 : mInner.mNamespaceID);
230 : }
231 :
232 0 : bool NameAndNamespaceEquals(nsINodeInfo *aNodeInfo) const
233 : {
234 : return aNodeInfo == this || aNodeInfo->Equals(mInner.mName,
235 0 : mInner.mNamespaceID);
236 : }
237 :
238 36250 : bool Equals(nsIAtom *aNameAtom) const
239 : {
240 36250 : return mInner.mName == aNameAtom;
241 : }
242 :
243 : bool Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom) const
244 : {
245 : return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom);
246 : }
247 :
248 159411 : bool Equals(nsIAtom *aNameAtom, PRInt32 aNamespaceID) const
249 : {
250 : return ((mInner.mName == aNameAtom) &&
251 159411 : (mInner.mNamespaceID == aNamespaceID));
252 : }
253 :
254 1834 : bool Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom,
255 : PRInt32 aNamespaceID) const
256 : {
257 : return ((mInner.mName == aNameAtom) &&
258 : (mInner.mPrefix == aPrefixAtom) &&
259 1834 : (mInner.mNamespaceID == aNamespaceID));
260 : }
261 :
262 149726 : bool NamespaceEquals(PRInt32 aNamespaceID) const
263 : {
264 149726 : return mInner.mNamespaceID == aNamespaceID;
265 : }
266 :
267 0 : bool Equals(const nsAString& aName) const
268 : {
269 0 : return mInner.mName->Equals(aName);
270 : }
271 :
272 : bool Equals(const nsAString& aName, const nsAString& aPrefix) const
273 : {
274 : return mInner.mName->Equals(aName) &&
275 : (mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) : aPrefix.IsEmpty());
276 : }
277 :
278 : bool Equals(const nsAString& aName, PRInt32 aNamespaceID) const
279 : {
280 : return mInner.mNamespaceID == aNamespaceID &&
281 : mInner.mName->Equals(aName);
282 : }
283 :
284 : bool Equals(const nsAString& aName, const nsAString& aPrefix,
285 : PRInt32 aNamespaceID) const
286 : {
287 : return mInner.mName->Equals(aName) && mInner.mNamespaceID == aNamespaceID &&
288 : (mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) : aPrefix.IsEmpty());
289 : }
290 :
291 : virtual bool NamespaceEquals(const nsAString& aNamespaceURI) const = 0;
292 :
293 34212 : bool QualifiedNameEquals(nsIAtom* aNameAtom) const
294 : {
295 34212 : NS_PRECONDITION(aNameAtom, "Must have name atom");
296 34212 : if (!GetPrefixAtom())
297 33102 : return Equals(aNameAtom);
298 :
299 1110 : return aNameAtom->Equals(mQualifiedName);
300 : }
301 :
302 2 : bool QualifiedNameEquals(const nsAString& aQualifiedName) const
303 : {
304 2 : return mQualifiedName == aQualifiedName;
305 : }
306 :
307 : /*
308 : * Retrieve a pointer to the document that owns this node info.
309 : */
310 1298683 : nsIDocument* GetDocument() const
311 : {
312 1298683 : return mDocument;
313 : }
314 :
315 : protected:
316 : /*
317 : * nsNodeInfoInner is used for two things:
318 : *
319 : * 1. as a member in nsNodeInfo for holding the name, prefix and
320 : * namespace ID
321 : * 2. as the hash key in the hash table in nsNodeInfoManager
322 : *
323 : * nsNodeInfoInner does not do any kind of reference counting,
324 : * that's up to the user of this class. Since nsNodeInfoInner is
325 : * typically used as a member of nsNodeInfo, the hash table doesn't
326 : * need to delete the keys. When the value (nsNodeInfo) is deleted
327 : * the key is automatically deleted.
328 : */
329 :
330 : class nsNodeInfoInner
331 : {
332 : public:
333 : nsNodeInfoInner()
334 : : mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_Unknown),
335 : mNodeType(0), mNameString(nsnull), mExtraName(nsnull)
336 : {
337 : }
338 54964 : nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
339 : PRUint16 aNodeType, nsIAtom* aExtraName)
340 : : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
341 54964 : mNodeType(aNodeType), mNameString(nsnull), mExtraName(aExtraName)
342 : {
343 54964 : }
344 207 : nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix,
345 : PRInt32 aNamespaceID, PRUint16 aNodeType)
346 : : mName(nsnull), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
347 207 : mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nsnull)
348 : {
349 207 : }
350 :
351 : nsIAtom* mName;
352 : nsIAtom* mPrefix;
353 : PRInt32 mNamespaceID;
354 : PRUint16 mNodeType; // As defined by nsIDOMNode.nodeType
355 : const nsAString* mNameString;
356 : nsIAtom* mExtraName; // Only used by PIs and DocTypes
357 : };
358 :
359 : // nsNodeInfoManager needs to pass mInner to the hash table.
360 : friend class nsNodeInfoManager;
361 :
362 : nsIDocument* mDocument; // Weak. Cache of mOwnerManager->mDocument
363 :
364 : nsNodeInfoInner mInner;
365 :
366 : nsCOMPtr<nsIAtom> mIDAttributeAtom;
367 : nsNodeInfoManager* mOwnerManager; // Strong reference!
368 :
369 : /*
370 : * Members for various functions of mName+mPrefix that we can be
371 : * asked to compute.
372 : */
373 :
374 : // Qualified name
375 : nsString mQualifiedName;
376 :
377 : // nodeName for the node.
378 : nsString mNodeName;
379 :
380 : // localName for the node. This is either equal to mInner.mName, or a
381 : // void string, depending on mInner.mNodeType.
382 : nsString mLocalName;
383 : };
384 :
385 : NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeInfo, NS_INODEINFO_IID)
386 :
387 : #endif /* nsINodeInfo_h___ */
|