1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 TransforMiiX XSLT processor 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) 2003
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Peter Van der Beken <peterv@propagandism.org>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef txXPathTreeWalker_h__
40 : #define txXPathTreeWalker_h__
41 :
42 : #include "txCore.h"
43 : #include "txXPathNode.h"
44 : #include "nsINodeInfo.h"
45 : #include "nsTArray.h"
46 :
47 : class nsIAtom;
48 : class nsIDOMDocument;
49 :
50 : class txUint32Array : public nsTArray<PRUint32>
51 84 : {
52 : public:
53 0 : bool AppendValue(PRUint32 aValue)
54 : {
55 0 : return AppendElement(aValue) != nsnull;
56 : }
57 0 : bool RemoveValueAt(PRUint32 aIndex)
58 : {
59 0 : if (aIndex < Length()) {
60 0 : RemoveElementAt(aIndex);
61 : }
62 0 : return true;
63 : }
64 0 : PRUint32 ValueAt(PRUint32 aIndex) const
65 : {
66 0 : return (aIndex < Length()) ? ElementAt(aIndex) : 0;
67 : }
68 : };
69 :
70 : class txXPathTreeWalker
71 42 : {
72 : public:
73 : txXPathTreeWalker(const txXPathTreeWalker& aOther);
74 : explicit txXPathTreeWalker(const txXPathNode& aNode);
75 :
76 : bool getAttr(nsIAtom* aLocalName, PRInt32 aNSID, nsAString& aValue) const;
77 : PRInt32 getNamespaceID() const;
78 : PRUint16 getNodeType() const;
79 : void appendNodeValue(nsAString& aResult) const;
80 : void getNodeName(nsAString& aName) const;
81 :
82 : void moveTo(const txXPathTreeWalker& aWalker);
83 :
84 : void moveToRoot();
85 : bool moveToParent();
86 : bool moveToElementById(const nsAString& aID);
87 : bool moveToFirstAttribute();
88 : bool moveToNextAttribute();
89 : bool moveToNamedAttribute(nsIAtom* aLocalName, PRInt32 aNSID);
90 : bool moveToFirstChild();
91 : bool moveToLastChild();
92 : bool moveToNextSibling();
93 : bool moveToPreviousSibling();
94 :
95 : bool isOnNode(const txXPathNode& aNode) const;
96 :
97 : const txXPathNode& getCurrentPosition() const;
98 :
99 : private:
100 : txXPathNode mPosition;
101 :
102 : bool moveToValidAttribute(PRUint32 aStartIndex);
103 : bool moveToSibling(PRInt32 aDir);
104 :
105 : PRUint32 mCurrentIndex;
106 : txUint32Array mDescendants;
107 : };
108 :
109 : class txXPathNodeUtils
110 : {
111 : public:
112 : static bool getAttr(const txXPathNode& aNode, nsIAtom* aLocalName,
113 : PRInt32 aNSID, nsAString& aValue);
114 : static already_AddRefed<nsIAtom> getLocalName(const txXPathNode& aNode);
115 : static nsIAtom* getPrefix(const txXPathNode& aNode);
116 : static void getLocalName(const txXPathNode& aNode, nsAString& aLocalName);
117 : static void getNodeName(const txXPathNode& aNode,
118 : nsAString& aName);
119 : static PRInt32 getNamespaceID(const txXPathNode& aNode);
120 : static void getNamespaceURI(const txXPathNode& aNode, nsAString& aURI);
121 : static PRUint16 getNodeType(const txXPathNode& aNode);
122 : static void appendNodeValue(const txXPathNode& aNode, nsAString& aResult);
123 : static bool isWhitespace(const txXPathNode& aNode);
124 : static txXPathNode* getOwnerDocument(const txXPathNode& aNode);
125 : static PRInt32 getUniqueIdentifier(const txXPathNode& aNode);
126 : static nsresult getXSLTId(const txXPathNode& aNode,
127 : const txXPathNode& aBase, nsAString& aResult);
128 : static void release(txXPathNode* aNode);
129 : static void getBaseURI(const txXPathNode& aNode, nsAString& aURI);
130 : static PRIntn comparePosition(const txXPathNode& aNode,
131 : const txXPathNode& aOtherNode);
132 : static bool localNameEquals(const txXPathNode& aNode,
133 : nsIAtom* aLocalName);
134 : static bool isRoot(const txXPathNode& aNode);
135 : static bool isElement(const txXPathNode& aNode);
136 : static bool isAttribute(const txXPathNode& aNode);
137 : static bool isProcessingInstruction(const txXPathNode& aNode);
138 : static bool isComment(const txXPathNode& aNode);
139 : static bool isText(const txXPathNode& aNode);
140 0 : static inline bool isHTMLElementInHTMLDocument(const txXPathNode& aNode)
141 : {
142 0 : if (!aNode.isContent()) {
143 0 : return false;
144 : }
145 0 : nsIContent* content = aNode.Content();
146 0 : return content->IsHTML() && content->IsInHTMLDocument();
147 : }
148 : };
149 :
150 : class txXPathNativeNode
151 : {
152 : public:
153 : static txXPathNode* createXPathNode(nsIDOMNode* aNode,
154 : bool aKeepRootAlive = false);
155 : static txXPathNode* createXPathNode(nsIContent* aContent,
156 : bool aKeepRootAlive = false);
157 : static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
158 : static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult);
159 : static nsIContent* getContent(const txXPathNode& aNode);
160 : static nsIDocument* getDocument(const txXPathNode& aNode);
161 : static void addRef(const txXPathNode& aNode)
162 : {
163 : NS_ADDREF(aNode.mNode);
164 : }
165 : static void release(const txXPathNode& aNode)
166 : {
167 : nsINode *node = aNode.mNode;
168 : NS_RELEASE(node);
169 : }
170 : };
171 :
172 : inline const txXPathNode&
173 84 : txXPathTreeWalker::getCurrentPosition() const
174 : {
175 84 : return mPosition;
176 : }
177 :
178 : inline bool
179 0 : txXPathTreeWalker::getAttr(nsIAtom* aLocalName, PRInt32 aNSID,
180 : nsAString& aValue) const
181 : {
182 0 : return txXPathNodeUtils::getAttr(mPosition, aLocalName, aNSID, aValue);
183 : }
184 :
185 : inline PRInt32
186 : txXPathTreeWalker::getNamespaceID() const
187 : {
188 : return txXPathNodeUtils::getNamespaceID(mPosition);
189 : }
190 :
191 : inline void
192 0 : txXPathTreeWalker::appendNodeValue(nsAString& aResult) const
193 : {
194 0 : txXPathNodeUtils::appendNodeValue(mPosition, aResult);
195 0 : }
196 :
197 : inline void
198 : txXPathTreeWalker::getNodeName(nsAString& aName) const
199 : {
200 : txXPathNodeUtils::getNodeName(mPosition, aName);
201 : }
202 :
203 : inline void
204 0 : txXPathTreeWalker::moveTo(const txXPathTreeWalker& aWalker)
205 : {
206 0 : nsINode *root = nsnull;
207 0 : if (mPosition.mRefCountRoot) {
208 0 : root = mPosition.Root();
209 : }
210 0 : mPosition.mIndex = aWalker.mPosition.mIndex;
211 0 : mPosition.mRefCountRoot = aWalker.mPosition.mRefCountRoot;
212 0 : mPosition.mNode = aWalker.mPosition.mNode;
213 0 : nsINode *newRoot = nsnull;
214 0 : if (mPosition.mRefCountRoot) {
215 0 : newRoot = mPosition.Root();
216 : }
217 0 : if (root != newRoot) {
218 0 : NS_IF_ADDREF(newRoot);
219 0 : NS_IF_RELEASE(root);
220 : }
221 :
222 0 : mCurrentIndex = aWalker.mCurrentIndex;
223 0 : mDescendants.Clear();
224 0 : }
225 :
226 : inline bool
227 0 : txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const
228 : {
229 0 : return (mPosition == aNode);
230 : }
231 :
232 : /* static */
233 : inline PRInt32
234 0 : txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode)
235 : {
236 0 : NS_PRECONDITION(!aNode.isAttribute(),
237 : "Not implemented for attributes.");
238 0 : return NS_PTR_TO_INT32(aNode.mNode);
239 : }
240 :
241 : /* static */
242 : inline void
243 0 : txXPathNodeUtils::release(txXPathNode* aNode)
244 : {
245 0 : NS_RELEASE(aNode->mNode);
246 0 : }
247 :
248 : /* static */
249 : inline bool
250 0 : txXPathNodeUtils::localNameEquals(const txXPathNode& aNode,
251 : nsIAtom* aLocalName)
252 : {
253 0 : if (aNode.isContent() &&
254 0 : aNode.Content()->IsElement()) {
255 0 : return aNode.Content()->NodeInfo()->Equals(aLocalName);
256 : }
257 :
258 0 : nsCOMPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
259 :
260 0 : return localName == aLocalName;
261 : }
262 :
263 : /* static */
264 : inline bool
265 0 : txXPathNodeUtils::isRoot(const txXPathNode& aNode)
266 : {
267 0 : return !aNode.isAttribute() && !aNode.mNode->GetNodeParent();
268 : }
269 :
270 : /* static */
271 : inline bool
272 0 : txXPathNodeUtils::isElement(const txXPathNode& aNode)
273 : {
274 0 : return aNode.isContent() &&
275 0 : aNode.Content()->IsElement();
276 : }
277 :
278 :
279 : /* static */
280 : inline bool
281 0 : txXPathNodeUtils::isAttribute(const txXPathNode& aNode)
282 : {
283 0 : return aNode.isAttribute();
284 : }
285 :
286 : /* static */
287 : inline bool
288 0 : txXPathNodeUtils::isProcessingInstruction(const txXPathNode& aNode)
289 : {
290 0 : return aNode.isContent() &&
291 0 : aNode.Content()->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION);
292 : }
293 :
294 : /* static */
295 : inline bool
296 0 : txXPathNodeUtils::isComment(const txXPathNode& aNode)
297 : {
298 0 : return aNode.isContent() &&
299 0 : aNode.Content()->IsNodeOfType(nsINode::eCOMMENT);
300 : }
301 :
302 : /* static */
303 : inline bool
304 42 : txXPathNodeUtils::isText(const txXPathNode& aNode)
305 : {
306 42 : return aNode.isContent() &&
307 42 : aNode.Content()->IsNodeOfType(nsINode::eTEXT);
308 : }
309 :
310 : #endif /* txXPathTreeWalker_h__ */
|