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 : /*
8 : * Class that represents a prefix/namespace/localName triple; a single
9 : * nodeinfo is shared by all elements in a document that have that
10 : * prefix, namespace, and localName.
11 : *
12 : * nsNodeInfoManagers are internal objects that manage a list of
13 : * NodeInfos, every document object should hold a strong reference to
14 : * a nsNodeInfoManager and every NodeInfo also holds a strong reference
15 : * to their owning manager. When a NodeInfo is no longer used it will
16 : * automatically remove itself from its owner manager, and when all
17 : * NodeInfos have been removed from a nsNodeInfoManager and all external
18 : * references are released the nsNodeInfoManager deletes itself.
19 : */
20 :
21 : #ifndef mozilla_dom_NodeInfo_h___
22 : #define mozilla_dom_NodeInfo_h___
23 :
24 : #include "nsCycleCollectionParticipant.h"
25 : #include "mozilla/dom/NameSpaceConstants.h"
26 : #include "nsStringGlue.h"
27 : #include "mozilla/Attributes.h"
28 : #include "nsIAtom.h"
29 :
30 : class nsIDocument;
31 : class nsNodeInfoManager;
32 :
33 : namespace mozilla {
34 : namespace dom {
35 :
36 : class NodeInfo final
37 : {
38 : public:
39 15218 : NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(NodeInfo)
40 16008 : NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS_WITH_CUSTOM_DELETE(NodeInfo)
41 :
42 : /*
43 : * Get the name from this node as a string, this does not include the prefix.
44 : *
45 : * For the HTML element "<body>" this will return "body" and for the XML
46 : * element "<html:body>" this will return "body".
47 : */
48 : void GetName(nsAString& aName) const;
49 :
50 : /*
51 : * Get the name from this node as an atom, this does not include the prefix.
52 : * This function never returns a null atom.
53 : *
54 : * For the HTML element "<body>" this will return the "body" atom and for
55 : * the XML element "<html:body>" this will return the "body" atom.
56 : */
57 53359 : nsIAtom* NameAtom() const
58 : {
59 53359 : return mInner.mName;
60 : }
61 :
62 : /*
63 : * Get the qualified name from this node as a string, the qualified name
64 : * includes the prefix, if one exists.
65 : *
66 : * For the HTML element "<body>" this will return "body" and for the XML
67 : * element "<html:body>" this will return "html:body".
68 : */
69 0 : const nsString& QualifiedName() const {
70 0 : return mQualifiedName;
71 : }
72 :
73 : /*
74 : * Returns the node's nodeName as defined in DOM Core
75 : */
76 0 : const nsString& NodeName() const {
77 0 : return mNodeName;
78 : }
79 :
80 : /*
81 : * Returns the node's localName as defined in DOM Core
82 : */
83 39 : const nsString& LocalName() const {
84 39 : return mLocalName;
85 : }
86 :
87 : /*
88 : * Get the prefix from this node as a string.
89 : *
90 : * For the HTML element "<body>" this will return a null string and for
91 : * the XML element "<html:body>" this will return the string "html".
92 : */
93 : void GetPrefix(nsAString& aPrefix) const;
94 :
95 : /*
96 : * Get the prefix from this node as an atom.
97 : *
98 : * For the HTML element "<body>" this will return a null atom and for
99 : * the XML element "<html:body>" this will return the "html" atom.
100 : */
101 2612 : nsIAtom* GetPrefixAtom() const
102 : {
103 2612 : return mInner.mPrefix;
104 : }
105 :
106 : /*
107 : * Get the namespace URI for a node, if the node has a namespace URI.
108 : */
109 : void GetNamespaceURI(nsAString& aNameSpaceURI) const;
110 :
111 : /*
112 : * Get the namespace ID for a node if the node has a namespace, if not this
113 : * returns kNameSpaceID_None.
114 : */
115 277618 : int32_t NamespaceID() const
116 : {
117 277618 : return mInner.mNamespaceID;
118 : }
119 :
120 : /*
121 : * Get the nodetype for the node. Returns the values specified in nsIDOMNode
122 : * for nsIDOMNode.nodeType
123 : */
124 6901 : uint16_t NodeType() const
125 : {
126 6901 : return mInner.mNodeType;
127 : }
128 :
129 : /*
130 : * Get the extra name, used by PIs and DocTypes, for the node.
131 : */
132 883 : nsIAtom* GetExtraName() const
133 : {
134 883 : return mInner.mExtraName;
135 : }
136 :
137 : /**
138 : * Get the owning node info manager. Only to be used inside Gecko, you can't
139 : * really do anything with the pointer outside Gecko anyway.
140 : */
141 4665 : nsNodeInfoManager* NodeInfoManager() const
142 : {
143 4665 : return mOwnerManager;
144 : }
145 :
146 : /*
147 : * Utility functions that can be used to check if a nodeinfo holds a specific
148 : * name, name and prefix, name and prefix and namespace ID, or just
149 : * namespace ID.
150 : */
151 : inline bool Equals(NodeInfo* aNodeInfo) const;
152 :
153 : bool NameAndNamespaceEquals(NodeInfo* aNodeInfo) const;
154 :
155 26904 : bool Equals(nsIAtom* aNameAtom) const
156 : {
157 26904 : return mInner.mName == aNameAtom;
158 : }
159 :
160 : bool Equals(nsIAtom* aNameAtom, nsIAtom* aPrefixAtom) const
161 : {
162 : return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom);
163 : }
164 :
165 59932 : bool Equals(nsIAtom* aNameAtom, int32_t aNamespaceID) const
166 : {
167 63038 : return ((mInner.mName == aNameAtom) &&
168 63038 : (mInner.mNamespaceID == aNamespaceID));
169 : }
170 :
171 0 : bool Equals(nsIAtom* aNameAtom, nsIAtom* aPrefixAtom, int32_t aNamespaceID) const
172 : {
173 0 : return ((mInner.mName == aNameAtom) &&
174 0 : (mInner.mPrefix == aPrefixAtom) &&
175 0 : (mInner.mNamespaceID == aNamespaceID));
176 : }
177 :
178 11950 : bool NamespaceEquals(int32_t aNamespaceID) const
179 : {
180 11950 : return mInner.mNamespaceID == aNamespaceID;
181 : }
182 :
183 : inline bool Equals(const nsAString& aName) const;
184 :
185 : inline bool Equals(const nsAString& aName, const nsAString& aPrefix) const;
186 :
187 : inline bool Equals(const nsAString& aName, int32_t aNamespaceID) const;
188 :
189 : inline bool Equals(const nsAString& aName, const nsAString& aPrefix, int32_t aNamespaceID) const;
190 :
191 : bool NamespaceEquals(const nsAString& aNamespaceURI) const;
192 :
193 : inline bool QualifiedNameEquals(nsIAtom* aNameAtom) const;
194 :
195 257 : bool QualifiedNameEquals(const nsAString& aQualifiedName) const
196 : {
197 257 : return mQualifiedName == aQualifiedName;
198 : }
199 :
200 : /*
201 : * Retrieve a pointer to the document that owns this node info.
202 : */
203 125828 : nsIDocument* GetDocument() const
204 : {
205 125828 : return mDocument;
206 : }
207 :
208 : private:
209 : NodeInfo() = delete;
210 : NodeInfo(const NodeInfo& aOther) = delete;
211 :
212 : // NodeInfo is only constructed by nsNodeInfoManager which is a friend class.
213 : // aName and aOwnerManager may not be null.
214 : NodeInfo(nsIAtom* aName, nsIAtom* aPrefix, int32_t aNamespaceID,
215 : uint16_t aNodeType, nsIAtom* aExtraName,
216 : nsNodeInfoManager* aOwnerManager);
217 :
218 : ~NodeInfo();
219 :
220 : public:
221 : bool CanSkip();
222 :
223 : /**
224 : * This method gets called by the cycle collector when it's time to delete
225 : * this object.
226 : */
227 : void DeleteCycleCollectable();
228 :
229 : protected:
230 : /*
231 : * NodeInfoInner is used for two things:
232 : *
233 : * 1. as a member in nsNodeInfo for holding the name, prefix and
234 : * namespace ID
235 : * 2. as the hash key in the hash table in nsNodeInfoManager
236 : *
237 : * NodeInfoInner does not do any kind of reference counting,
238 : * that's up to the user of this class. Since NodeInfoInner is
239 : * typically used as a member of NodeInfo, the hash table doesn't
240 : * need to delete the keys. When the value (NodeInfo) is deleted
241 : * the key is automatically deleted.
242 : */
243 :
244 4655 : class NodeInfoInner
245 : {
246 : public:
247 1039 : NodeInfoInner()
248 1039 : : mName(nullptr), mPrefix(nullptr), mNamespaceID(kNameSpaceID_Unknown),
249 1039 : mNodeType(0), mNameString(nullptr), mExtraName(nullptr)
250 : {
251 1039 : }
252 3756 : NodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, int32_t aNamespaceID,
253 : uint16_t aNodeType, nsIAtom* aExtraName)
254 3756 : : mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
255 3756 : mNodeType(aNodeType), mNameString(nullptr), mExtraName(aExtraName)
256 : {
257 3756 : }
258 620 : NodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix,
259 : int32_t aNamespaceID, uint16_t aNodeType)
260 620 : : mName(nullptr), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
261 620 : mNodeType(aNodeType), mNameString(&aTmpName), mExtraName(nullptr)
262 : {
263 620 : }
264 :
265 : nsCOMPtr<nsIAtom> mName;
266 : nsCOMPtr<nsIAtom> mPrefix;
267 : int32_t mNamespaceID;
268 : uint16_t mNodeType; // As defined by nsIDOMNode.nodeType
269 : const nsAString* mNameString;
270 : nsCOMPtr<nsIAtom> mExtraName; // Only used by PIs and DocTypes
271 : };
272 :
273 : // nsNodeInfoManager needs to pass mInner to the hash table.
274 : friend class ::nsNodeInfoManager;
275 :
276 : // This is a non-owning reference, but it's safe since it's set to nullptr
277 : // by nsNodeInfoManager::DropDocumentReference when the document is destroyed.
278 : nsIDocument* MOZ_NON_OWNING_REF mDocument; // Cache of mOwnerManager->mDocument
279 :
280 : NodeInfoInner mInner;
281 :
282 : RefPtr<nsNodeInfoManager> mOwnerManager;
283 :
284 : /*
285 : * Members for various functions of mName+mPrefix that we can be
286 : * asked to compute.
287 : */
288 :
289 : // Qualified name
290 : nsString mQualifiedName;
291 :
292 : // nodeName for the node.
293 : nsString mNodeName;
294 :
295 : // localName for the node. This is either equal to mInner.mName, or a
296 : // void string, depending on mInner.mNodeType.
297 : nsString mLocalName;
298 : };
299 :
300 : } // namespace dom
301 : } // namespace mozilla
302 :
303 : #endif /* mozilla_dom_NodeInfo_h___ */
|