Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 :
6 : #ifndef txXPathTreeWalker_h__
7 : #define txXPathTreeWalker_h__
8 :
9 : #include "txCore.h"
10 : #include "txXPathNode.h"
11 : #include "nsIContentInlines.h"
12 : #include "nsTArray.h"
13 :
14 : class nsIAtom;
15 : class nsIDOMDocument;
16 :
17 0 : class txXPathTreeWalker
18 : {
19 : public:
20 : txXPathTreeWalker(const txXPathTreeWalker& aOther);
21 : explicit txXPathTreeWalker(const txXPathNode& aNode);
22 :
23 : bool getAttr(nsIAtom* aLocalName, int32_t aNSID, nsAString& aValue) const;
24 : int32_t getNamespaceID() const;
25 : uint16_t getNodeType() const;
26 : void appendNodeValue(nsAString& aResult) const;
27 : void getNodeName(nsAString& aName) const;
28 :
29 : void moveTo(const txXPathTreeWalker& aWalker);
30 :
31 : void moveToRoot();
32 : bool moveToParent();
33 : bool moveToElementById(const nsAString& aID);
34 : bool moveToFirstAttribute();
35 : bool moveToNextAttribute();
36 : bool moveToNamedAttribute(nsIAtom* aLocalName, int32_t aNSID);
37 : bool moveToFirstChild();
38 : bool moveToLastChild();
39 : bool moveToNextSibling();
40 : bool moveToPreviousSibling();
41 :
42 : bool isOnNode(const txXPathNode& aNode) const;
43 :
44 : const txXPathNode& getCurrentPosition() const;
45 :
46 : private:
47 : txXPathNode mPosition;
48 :
49 : bool moveToValidAttribute(uint32_t aStartIndex);
50 : };
51 :
52 : class txXPathNodeUtils
53 : {
54 : public:
55 : static bool getAttr(const txXPathNode& aNode, nsIAtom* aLocalName,
56 : int32_t aNSID, nsAString& aValue);
57 : static already_AddRefed<nsIAtom> getLocalName(const txXPathNode& aNode);
58 : static nsIAtom* getPrefix(const txXPathNode& aNode);
59 : static void getLocalName(const txXPathNode& aNode, nsAString& aLocalName);
60 : static void getNodeName(const txXPathNode& aNode,
61 : nsAString& aName);
62 : static int32_t getNamespaceID(const txXPathNode& aNode);
63 : static void getNamespaceURI(const txXPathNode& aNode, nsAString& aURI);
64 : static uint16_t getNodeType(const txXPathNode& aNode);
65 : static void appendNodeValue(const txXPathNode& aNode, nsAString& aResult);
66 : static bool isWhitespace(const txXPathNode& aNode);
67 : static txXPathNode* getOwnerDocument(const txXPathNode& aNode);
68 : static int32_t getUniqueIdentifier(const txXPathNode& aNode);
69 : static nsresult getXSLTId(const txXPathNode& aNode,
70 : const txXPathNode& aBase, nsAString& aResult);
71 : static void release(txXPathNode* aNode);
72 : static nsresult getBaseURI(const txXPathNode& aNode, nsAString& aURI);
73 : static int comparePosition(const txXPathNode& aNode,
74 : const txXPathNode& aOtherNode);
75 : static bool localNameEquals(const txXPathNode& aNode,
76 : nsIAtom* aLocalName);
77 : static bool isRoot(const txXPathNode& aNode);
78 : static bool isElement(const txXPathNode& aNode);
79 : static bool isAttribute(const txXPathNode& aNode);
80 : static bool isProcessingInstruction(const txXPathNode& aNode);
81 : static bool isComment(const txXPathNode& aNode);
82 : static bool isText(const txXPathNode& aNode);
83 0 : static inline bool isHTMLElementInHTMLDocument(const txXPathNode& aNode)
84 : {
85 0 : if (!aNode.isContent()) {
86 0 : return false;
87 : }
88 0 : nsIContent* content = aNode.Content();
89 0 : return content->IsHTMLElement() && content->IsInHTMLDocument();
90 : }
91 : };
92 :
93 : class txXPathNativeNode
94 : {
95 : public:
96 : static txXPathNode* createXPathNode(nsINode* aNode,
97 : bool aKeepRootAlive = false);
98 0 : static txXPathNode* createXPathNode(nsIDOMNode* aNode,
99 : bool aKeepRootAlive = false)
100 : {
101 0 : nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
102 0 : return createXPathNode(node, aKeepRootAlive);
103 : }
104 : static txXPathNode* createXPathNode(nsIContent* aContent,
105 : bool aKeepRootAlive = false);
106 : static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
107 : static nsINode* getNode(const txXPathNode& aNode);
108 0 : static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
109 : {
110 0 : return CallQueryInterface(getNode(aNode), aResult);
111 : }
112 : static nsIContent* getContent(const txXPathNode& aNode);
113 : static nsIDocument* getDocument(const txXPathNode& aNode);
114 : static void addRef(const txXPathNode& aNode)
115 : {
116 : NS_ADDREF(aNode.mNode);
117 : }
118 : static void release(const txXPathNode& aNode)
119 : {
120 : nsINode *node = aNode.mNode;
121 : NS_RELEASE(node);
122 : }
123 : };
124 :
125 : inline const txXPathNode&
126 0 : txXPathTreeWalker::getCurrentPosition() const
127 : {
128 0 : return mPosition;
129 : }
130 :
131 : inline bool
132 0 : txXPathTreeWalker::getAttr(nsIAtom* aLocalName, int32_t aNSID,
133 : nsAString& aValue) const
134 : {
135 0 : return txXPathNodeUtils::getAttr(mPosition, aLocalName, aNSID, aValue);
136 : }
137 :
138 : inline int32_t
139 : txXPathTreeWalker::getNamespaceID() const
140 : {
141 : return txXPathNodeUtils::getNamespaceID(mPosition);
142 : }
143 :
144 : inline void
145 0 : txXPathTreeWalker::appendNodeValue(nsAString& aResult) const
146 : {
147 0 : txXPathNodeUtils::appendNodeValue(mPosition, aResult);
148 0 : }
149 :
150 : inline void
151 : txXPathTreeWalker::getNodeName(nsAString& aName) const
152 : {
153 : txXPathNodeUtils::getNodeName(mPosition, aName);
154 : }
155 :
156 : inline void
157 0 : txXPathTreeWalker::moveTo(const txXPathTreeWalker& aWalker)
158 : {
159 0 : nsINode *root = nullptr;
160 0 : if (mPosition.mRefCountRoot) {
161 0 : root = mPosition.Root();
162 : }
163 0 : mPosition.mIndex = aWalker.mPosition.mIndex;
164 0 : mPosition.mRefCountRoot = aWalker.mPosition.mRefCountRoot;
165 0 : mPosition.mNode = aWalker.mPosition.mNode;
166 0 : nsINode *newRoot = nullptr;
167 0 : if (mPosition.mRefCountRoot) {
168 0 : newRoot = mPosition.Root();
169 : }
170 0 : if (root != newRoot) {
171 0 : NS_IF_ADDREF(newRoot);
172 0 : NS_IF_RELEASE(root);
173 : }
174 0 : }
175 :
176 : inline bool
177 0 : txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const
178 : {
179 0 : return (mPosition == aNode);
180 : }
181 :
182 : /* static */
183 : inline int32_t
184 0 : txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode)
185 : {
186 0 : NS_PRECONDITION(!aNode.isAttribute(),
187 : "Not implemented for attributes.");
188 0 : return NS_PTR_TO_INT32(aNode.mNode);
189 : }
190 :
191 : /* static */
192 : inline void
193 0 : txXPathNodeUtils::release(txXPathNode* aNode)
194 : {
195 0 : NS_RELEASE(aNode->mNode);
196 0 : }
197 :
198 : /* static */
199 : inline bool
200 0 : txXPathNodeUtils::localNameEquals(const txXPathNode& aNode,
201 : nsIAtom* aLocalName)
202 : {
203 0 : if (aNode.isContent() &&
204 0 : aNode.Content()->IsElement()) {
205 0 : return aNode.Content()->NodeInfo()->Equals(aLocalName);
206 : }
207 :
208 0 : nsCOMPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
209 :
210 0 : return localName == aLocalName;
211 : }
212 :
213 : /* static */
214 : inline bool
215 0 : txXPathNodeUtils::isRoot(const txXPathNode& aNode)
216 : {
217 0 : return !aNode.isAttribute() && !aNode.mNode->GetParentNode();
218 : }
219 :
220 : /* static */
221 : inline bool
222 0 : txXPathNodeUtils::isElement(const txXPathNode& aNode)
223 : {
224 0 : return aNode.isContent() &&
225 0 : aNode.Content()->IsElement();
226 : }
227 :
228 :
229 : /* static */
230 : inline bool
231 0 : txXPathNodeUtils::isAttribute(const txXPathNode& aNode)
232 : {
233 0 : return aNode.isAttribute();
234 : }
235 :
236 : /* static */
237 : inline bool
238 0 : txXPathNodeUtils::isProcessingInstruction(const txXPathNode& aNode)
239 : {
240 0 : return aNode.isContent() &&
241 0 : aNode.Content()->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION);
242 : }
243 :
244 : /* static */
245 : inline bool
246 0 : txXPathNodeUtils::isComment(const txXPathNode& aNode)
247 : {
248 0 : return aNode.isContent() &&
249 0 : aNode.Content()->IsNodeOfType(nsINode::eCOMMENT);
250 : }
251 :
252 : /* static */
253 : inline bool
254 0 : txXPathNodeUtils::isText(const txXPathNode& aNode)
255 : {
256 0 : return aNode.isContent() &&
257 0 : aNode.Content()->IsNodeOfType(nsINode::eTEXT);
258 : }
259 :
260 : #endif /* txXPathTreeWalker_h__ */
|