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/. */
6 #ifndef txXPathTreeWalker_h__
7 #define txXPathTreeWalker_h__
10 #include "txXPathNode.h"
11 #include "nsIContentInlines.h"
17 class txUint32Array
: public nsTArray
<uint32_t>
20 bool AppendValue(uint32_t aValue
)
22 return AppendElement(aValue
) != nullptr;
24 bool RemoveValueAt(uint32_t aIndex
)
26 if (aIndex
< Length()) {
27 RemoveElementAt(aIndex
);
31 uint32_t ValueAt(uint32_t aIndex
) const
33 return (aIndex
< Length()) ? ElementAt(aIndex
) : 0;
37 class txXPathTreeWalker
40 txXPathTreeWalker(const txXPathTreeWalker
& aOther
);
41 explicit txXPathTreeWalker(const txXPathNode
& aNode
);
43 bool getAttr(nsIAtom
* aLocalName
, int32_t aNSID
, nsAString
& aValue
) const;
44 int32_t getNamespaceID() const;
45 uint16_t getNodeType() const;
46 void appendNodeValue(nsAString
& aResult
) const;
47 void getNodeName(nsAString
& aName
) const;
49 void moveTo(const txXPathTreeWalker
& aWalker
);
53 bool moveToElementById(const nsAString
& aID
);
54 bool moveToFirstAttribute();
55 bool moveToNextAttribute();
56 bool moveToNamedAttribute(nsIAtom
* aLocalName
, int32_t aNSID
);
57 bool moveToFirstChild();
58 bool moveToLastChild();
59 bool moveToNextSibling();
60 bool moveToPreviousSibling();
62 bool isOnNode(const txXPathNode
& aNode
) const;
64 const txXPathNode
& getCurrentPosition() const;
67 txXPathNode mPosition
;
69 bool moveToValidAttribute(uint32_t aStartIndex
);
70 bool moveToSibling(int32_t aDir
);
72 uint32_t mCurrentIndex
;
73 txUint32Array mDescendants
;
76 class txXPathNodeUtils
79 static bool getAttr(const txXPathNode
& aNode
, nsIAtom
* aLocalName
,
80 int32_t aNSID
, nsAString
& aValue
);
81 static already_AddRefed
<nsIAtom
> getLocalName(const txXPathNode
& aNode
);
82 static nsIAtom
* getPrefix(const txXPathNode
& aNode
);
83 static void getLocalName(const txXPathNode
& aNode
, nsAString
& aLocalName
);
84 static void getNodeName(const txXPathNode
& aNode
,
86 static int32_t getNamespaceID(const txXPathNode
& aNode
);
87 static void getNamespaceURI(const txXPathNode
& aNode
, nsAString
& aURI
);
88 static uint16_t getNodeType(const txXPathNode
& aNode
);
89 static void appendNodeValue(const txXPathNode
& aNode
, nsAString
& aResult
);
90 static bool isWhitespace(const txXPathNode
& aNode
);
91 static txXPathNode
* getOwnerDocument(const txXPathNode
& aNode
);
92 static int32_t getUniqueIdentifier(const txXPathNode
& aNode
);
93 static nsresult
getXSLTId(const txXPathNode
& aNode
,
94 const txXPathNode
& aBase
, nsAString
& aResult
);
95 static void release(txXPathNode
* aNode
);
96 static void getBaseURI(const txXPathNode
& aNode
, nsAString
& aURI
);
97 static int comparePosition(const txXPathNode
& aNode
,
98 const txXPathNode
& aOtherNode
);
99 static bool localNameEquals(const txXPathNode
& aNode
,
100 nsIAtom
* aLocalName
);
101 static bool isRoot(const txXPathNode
& aNode
);
102 static bool isElement(const txXPathNode
& aNode
);
103 static bool isAttribute(const txXPathNode
& aNode
);
104 static bool isProcessingInstruction(const txXPathNode
& aNode
);
105 static bool isComment(const txXPathNode
& aNode
);
106 static bool isText(const txXPathNode
& aNode
);
107 static inline bool isHTMLElementInHTMLDocument(const txXPathNode
& aNode
)
109 if (!aNode
.isContent()) {
112 nsIContent
* content
= aNode
.Content();
113 return content
->IsHTML() && content
->IsInHTMLDocument();
117 class txXPathNativeNode
120 static txXPathNode
* createXPathNode(nsINode
* aNode
,
121 bool aKeepRootAlive
= false);
122 static txXPathNode
* createXPathNode(nsIDOMNode
* aNode
,
123 bool aKeepRootAlive
= false)
125 nsCOMPtr
<nsINode
> node
= do_QueryInterface(aNode
);
126 return createXPathNode(node
, aKeepRootAlive
);
128 static txXPathNode
* createXPathNode(nsIContent
* aContent
,
129 bool aKeepRootAlive
= false);
130 static txXPathNode
* createXPathNode(nsIDOMDocument
* aDocument
);
131 static nsINode
* getNode(const txXPathNode
& aNode
);
132 static nsresult
getNode(const txXPathNode
& aNode
, nsIDOMNode
** aResult
)
134 return CallQueryInterface(getNode(aNode
), aResult
);
136 static nsIContent
* getContent(const txXPathNode
& aNode
);
137 static nsIDocument
* getDocument(const txXPathNode
& aNode
);
138 static void addRef(const txXPathNode
& aNode
)
140 NS_ADDREF(aNode
.mNode
);
142 static void release(const txXPathNode
& aNode
)
144 nsINode
*node
= aNode
.mNode
;
149 inline const txXPathNode
&
150 txXPathTreeWalker::getCurrentPosition() const
156 txXPathTreeWalker::getAttr(nsIAtom
* aLocalName
, int32_t aNSID
,
157 nsAString
& aValue
) const
159 return txXPathNodeUtils::getAttr(mPosition
, aLocalName
, aNSID
, aValue
);
163 txXPathTreeWalker::getNamespaceID() const
165 return txXPathNodeUtils::getNamespaceID(mPosition
);
169 txXPathTreeWalker::appendNodeValue(nsAString
& aResult
) const
171 txXPathNodeUtils::appendNodeValue(mPosition
, aResult
);
175 txXPathTreeWalker::getNodeName(nsAString
& aName
) const
177 txXPathNodeUtils::getNodeName(mPosition
, aName
);
181 txXPathTreeWalker::moveTo(const txXPathTreeWalker
& aWalker
)
183 nsINode
*root
= nullptr;
184 if (mPosition
.mRefCountRoot
) {
185 root
= mPosition
.Root();
187 mPosition
.mIndex
= aWalker
.mPosition
.mIndex
;
188 mPosition
.mRefCountRoot
= aWalker
.mPosition
.mRefCountRoot
;
189 mPosition
.mNode
= aWalker
.mPosition
.mNode
;
190 nsINode
*newRoot
= nullptr;
191 if (mPosition
.mRefCountRoot
) {
192 newRoot
= mPosition
.Root();
194 if (root
!= newRoot
) {
195 NS_IF_ADDREF(newRoot
);
199 mCurrentIndex
= aWalker
.mCurrentIndex
;
200 mDescendants
.Clear();
204 txXPathTreeWalker::isOnNode(const txXPathNode
& aNode
) const
206 return (mPosition
== aNode
);
211 txXPathNodeUtils::getUniqueIdentifier(const txXPathNode
& aNode
)
213 NS_PRECONDITION(!aNode
.isAttribute(),
214 "Not implemented for attributes.");
215 return NS_PTR_TO_INT32(aNode
.mNode
);
220 txXPathNodeUtils::release(txXPathNode
* aNode
)
222 NS_RELEASE(aNode
->mNode
);
227 txXPathNodeUtils::localNameEquals(const txXPathNode
& aNode
,
230 if (aNode
.isContent() &&
231 aNode
.Content()->IsElement()) {
232 return aNode
.Content()->NodeInfo()->Equals(aLocalName
);
235 nsCOMPtr
<nsIAtom
> localName
= txXPathNodeUtils::getLocalName(aNode
);
237 return localName
== aLocalName
;
242 txXPathNodeUtils::isRoot(const txXPathNode
& aNode
)
244 return !aNode
.isAttribute() && !aNode
.mNode
->GetParentNode();
249 txXPathNodeUtils::isElement(const txXPathNode
& aNode
)
251 return aNode
.isContent() &&
252 aNode
.Content()->IsElement();
258 txXPathNodeUtils::isAttribute(const txXPathNode
& aNode
)
260 return aNode
.isAttribute();
265 txXPathNodeUtils::isProcessingInstruction(const txXPathNode
& aNode
)
267 return aNode
.isContent() &&
268 aNode
.Content()->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION
);
273 txXPathNodeUtils::isComment(const txXPathNode
& aNode
)
275 return aNode
.isContent() &&
276 aNode
.Content()->IsNodeOfType(nsINode::eCOMMENT
);
281 txXPathNodeUtils::isText(const txXPathNode
& aNode
)
283 return aNode
.isContent() &&
284 aNode
.Content()->IsNodeOfType(nsINode::eTEXT
);
287 #endif /* txXPathTreeWalker_h__ */