summaryrefslogtreecommitdiffstats
path: root/dom/xslt/xpath/txXPathTreeWalker.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/xslt/xpath/txXPathTreeWalker.h')
-rw-r--r--dom/xslt/xpath/txXPathTreeWalker.h287
1 files changed, 287 insertions, 0 deletions
diff --git a/dom/xslt/xpath/txXPathTreeWalker.h b/dom/xslt/xpath/txXPathTreeWalker.h
new file mode 100644
index 000000000..99a07ffe7
--- /dev/null
+++ b/dom/xslt/xpath/txXPathTreeWalker.h
@@ -0,0 +1,287 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef txXPathTreeWalker_h__
+#define txXPathTreeWalker_h__
+
+#include "txCore.h"
+#include "txXPathNode.h"
+#include "nsIContentInlines.h"
+#include "nsTArray.h"
+
+class nsIAtom;
+class nsIDOMDocument;
+
+class txUint32Array : public nsTArray<uint32_t>
+{
+public:
+ bool AppendValue(uint32_t aValue)
+ {
+ return AppendElement(aValue) != nullptr;
+ }
+ bool RemoveValueAt(uint32_t aIndex)
+ {
+ if (aIndex < Length()) {
+ RemoveElementAt(aIndex);
+ }
+ return true;
+ }
+ uint32_t ValueAt(uint32_t aIndex) const
+ {
+ return (aIndex < Length()) ? ElementAt(aIndex) : 0;
+ }
+};
+
+class txXPathTreeWalker
+{
+public:
+ txXPathTreeWalker(const txXPathTreeWalker& aOther);
+ explicit txXPathTreeWalker(const txXPathNode& aNode);
+
+ bool getAttr(nsIAtom* aLocalName, int32_t aNSID, nsAString& aValue) const;
+ int32_t getNamespaceID() const;
+ uint16_t getNodeType() const;
+ void appendNodeValue(nsAString& aResult) const;
+ void getNodeName(nsAString& aName) const;
+
+ void moveTo(const txXPathTreeWalker& aWalker);
+
+ void moveToRoot();
+ bool moveToParent();
+ bool moveToElementById(const nsAString& aID);
+ bool moveToFirstAttribute();
+ bool moveToNextAttribute();
+ bool moveToNamedAttribute(nsIAtom* aLocalName, int32_t aNSID);
+ bool moveToFirstChild();
+ bool moveToLastChild();
+ bool moveToNextSibling();
+ bool moveToPreviousSibling();
+
+ bool isOnNode(const txXPathNode& aNode) const;
+
+ const txXPathNode& getCurrentPosition() const;
+
+private:
+ txXPathNode mPosition;
+
+ bool moveToValidAttribute(uint32_t aStartIndex);
+ bool moveToSibling(int32_t aDir);
+
+ uint32_t mCurrentIndex;
+ txUint32Array mDescendants;
+};
+
+class txXPathNodeUtils
+{
+public:
+ static bool getAttr(const txXPathNode& aNode, nsIAtom* aLocalName,
+ int32_t aNSID, nsAString& aValue);
+ static already_AddRefed<nsIAtom> getLocalName(const txXPathNode& aNode);
+ static nsIAtom* getPrefix(const txXPathNode& aNode);
+ static void getLocalName(const txXPathNode& aNode, nsAString& aLocalName);
+ static void getNodeName(const txXPathNode& aNode,
+ nsAString& aName);
+ static int32_t getNamespaceID(const txXPathNode& aNode);
+ static void getNamespaceURI(const txXPathNode& aNode, nsAString& aURI);
+ static uint16_t getNodeType(const txXPathNode& aNode);
+ static void appendNodeValue(const txXPathNode& aNode, nsAString& aResult);
+ static bool isWhitespace(const txXPathNode& aNode);
+ static txXPathNode* getOwnerDocument(const txXPathNode& aNode);
+ static int32_t getUniqueIdentifier(const txXPathNode& aNode);
+ static nsresult getXSLTId(const txXPathNode& aNode,
+ const txXPathNode& aBase, nsAString& aResult);
+ static void release(txXPathNode* aNode);
+ static nsresult getBaseURI(const txXPathNode& aNode, nsAString& aURI);
+ static int comparePosition(const txXPathNode& aNode,
+ const txXPathNode& aOtherNode);
+ static bool localNameEquals(const txXPathNode& aNode,
+ nsIAtom* aLocalName);
+ static bool isRoot(const txXPathNode& aNode);
+ static bool isElement(const txXPathNode& aNode);
+ static bool isAttribute(const txXPathNode& aNode);
+ static bool isProcessingInstruction(const txXPathNode& aNode);
+ static bool isComment(const txXPathNode& aNode);
+ static bool isText(const txXPathNode& aNode);
+ static inline bool isHTMLElementInHTMLDocument(const txXPathNode& aNode)
+ {
+ if (!aNode.isContent()) {
+ return false;
+ }
+ nsIContent* content = aNode.Content();
+ return content->IsHTMLElement() && content->IsInHTMLDocument();
+ }
+};
+
+class txXPathNativeNode
+{
+public:
+ static txXPathNode* createXPathNode(nsINode* aNode,
+ bool aKeepRootAlive = false);
+ static txXPathNode* createXPathNode(nsIDOMNode* aNode,
+ bool aKeepRootAlive = false)
+ {
+ nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+ return createXPathNode(node, aKeepRootAlive);
+ }
+ static txXPathNode* createXPathNode(nsIContent* aContent,
+ bool aKeepRootAlive = false);
+ static txXPathNode* createXPathNode(nsIDOMDocument* aDocument);
+ static nsINode* getNode(const txXPathNode& aNode);
+ static nsresult getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
+ {
+ return CallQueryInterface(getNode(aNode), aResult);
+ }
+ static nsIContent* getContent(const txXPathNode& aNode);
+ static nsIDocument* getDocument(const txXPathNode& aNode);
+ static void addRef(const txXPathNode& aNode)
+ {
+ NS_ADDREF(aNode.mNode);
+ }
+ static void release(const txXPathNode& aNode)
+ {
+ nsINode *node = aNode.mNode;
+ NS_RELEASE(node);
+ }
+};
+
+inline const txXPathNode&
+txXPathTreeWalker::getCurrentPosition() const
+{
+ return mPosition;
+}
+
+inline bool
+txXPathTreeWalker::getAttr(nsIAtom* aLocalName, int32_t aNSID,
+ nsAString& aValue) const
+{
+ return txXPathNodeUtils::getAttr(mPosition, aLocalName, aNSID, aValue);
+}
+
+inline int32_t
+txXPathTreeWalker::getNamespaceID() const
+{
+ return txXPathNodeUtils::getNamespaceID(mPosition);
+}
+
+inline void
+txXPathTreeWalker::appendNodeValue(nsAString& aResult) const
+{
+ txXPathNodeUtils::appendNodeValue(mPosition, aResult);
+}
+
+inline void
+txXPathTreeWalker::getNodeName(nsAString& aName) const
+{
+ txXPathNodeUtils::getNodeName(mPosition, aName);
+}
+
+inline void
+txXPathTreeWalker::moveTo(const txXPathTreeWalker& aWalker)
+{
+ nsINode *root = nullptr;
+ if (mPosition.mRefCountRoot) {
+ root = mPosition.Root();
+ }
+ mPosition.mIndex = aWalker.mPosition.mIndex;
+ mPosition.mRefCountRoot = aWalker.mPosition.mRefCountRoot;
+ mPosition.mNode = aWalker.mPosition.mNode;
+ nsINode *newRoot = nullptr;
+ if (mPosition.mRefCountRoot) {
+ newRoot = mPosition.Root();
+ }
+ if (root != newRoot) {
+ NS_IF_ADDREF(newRoot);
+ NS_IF_RELEASE(root);
+ }
+
+ mCurrentIndex = aWalker.mCurrentIndex;
+ mDescendants.Clear();
+}
+
+inline bool
+txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const
+{
+ return (mPosition == aNode);
+}
+
+/* static */
+inline int32_t
+txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode)
+{
+ NS_PRECONDITION(!aNode.isAttribute(),
+ "Not implemented for attributes.");
+ return NS_PTR_TO_INT32(aNode.mNode);
+}
+
+/* static */
+inline void
+txXPathNodeUtils::release(txXPathNode* aNode)
+{
+ NS_RELEASE(aNode->mNode);
+}
+
+/* static */
+inline bool
+txXPathNodeUtils::localNameEquals(const txXPathNode& aNode,
+ nsIAtom* aLocalName)
+{
+ if (aNode.isContent() &&
+ aNode.Content()->IsElement()) {
+ return aNode.Content()->NodeInfo()->Equals(aLocalName);
+ }
+
+ nsCOMPtr<nsIAtom> localName = txXPathNodeUtils::getLocalName(aNode);
+
+ return localName == aLocalName;
+}
+
+/* static */
+inline bool
+txXPathNodeUtils::isRoot(const txXPathNode& aNode)
+{
+ return !aNode.isAttribute() && !aNode.mNode->GetParentNode();
+}
+
+/* static */
+inline bool
+txXPathNodeUtils::isElement(const txXPathNode& aNode)
+{
+ return aNode.isContent() &&
+ aNode.Content()->IsElement();
+}
+
+
+/* static */
+inline bool
+txXPathNodeUtils::isAttribute(const txXPathNode& aNode)
+{
+ return aNode.isAttribute();
+}
+
+/* static */
+inline bool
+txXPathNodeUtils::isProcessingInstruction(const txXPathNode& aNode)
+{
+ return aNode.isContent() &&
+ aNode.Content()->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION);
+}
+
+/* static */
+inline bool
+txXPathNodeUtils::isComment(const txXPathNode& aNode)
+{
+ return aNode.isContent() &&
+ aNode.Content()->IsNodeOfType(nsINode::eCOMMENT);
+}
+
+/* static */
+inline bool
+txXPathNodeUtils::isText(const txXPathNode& aNode)
+{
+ return aNode.isContent() &&
+ aNode.Content()->IsNodeOfType(nsINode::eTEXT);
+}
+
+#endif /* txXPathTreeWalker_h__ */