/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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 nsAtom; class txXPathTreeWalker { public: txXPathTreeWalker(const txXPathTreeWalker& aOther); explicit txXPathTreeWalker(const txXPathNode& aNode); bool getAttr(nsAtom* 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(nsAtom* 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); }; class txXPathNodeUtils { public: static bool getAttr(const txXPathNode& aNode, nsAtom* aLocalName, int32_t aNSID, nsAString& aValue); static already_AddRefed getLocalName(const txXPathNode& aNode); static nsAtom* 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, nsAtom* 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(nsIContent* aContent, bool aKeepRootAlive = false); static txXPathNode* createXPathNode(mozilla::dom::Document* aDocument); static nsINode* getNode(const txXPathNode& aNode); static nsIContent* getContent(const txXPathNode& aNode); static mozilla::dom::Document* 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(nsAtom* 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); } } inline bool txXPathTreeWalker::isOnNode(const txXPathNode& aNode) const { return (mPosition == aNode); } /* static */ inline int32_t txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode) { MOZ_ASSERT(!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, nsAtom* aLocalName) { if (aNode.isContent() && aNode.Content()->IsElement()) { return aNode.Content()->NodeInfo()->Equals(aLocalName); } RefPtr 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()->IsProcessingInstruction(); } /* static */ inline bool txXPathNodeUtils::isComment(const txXPathNode& aNode) { return aNode.isContent() && aNode.Content()->IsComment(); } /* static */ inline bool txXPathNodeUtils::isText(const txXPathNode& aNode) { return aNode.isContent() && aNode.Content()->IsText(); } #endif /* txXPathTreeWalker_h__ */