tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

txXPathNode.h (4904B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      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 txXPathNode_h__
      7 #define txXPathNode_h__
      8 
      9 #include "mozilla/dom/Document.h"
     10 #include "nsIContent.h"
     11 #include "nsINode.h"
     12 #include "nsNameSpaceManager.h"
     13 
     14 using txXPathNodeType = nsINode;
     15 
     16 /**
     17 * txXPathNode represents a node in XPath's data model (which is a bit different
     18 * from the DOM's). While XPath 1.0 has 7 node types, we essentially deal with 3
     19 * kinds: a document node, any other node type that is backed by an
     20 * implementation of nsIContent in Gecko, and attribute nodes. Because we try to
     21 * avoid creating actual node objects for attribute nodes in Gecko's DOM, we
     22 * store attribute nodes as a pointer to their owner element and an index into
     23 * that element's attribute node list. So to represent the 3 kinds of node we
     24 * need to store:
     25 *
     26 *  - a pointer to a document (a nsIDocument as a nsINode pointer)
     27 *  - a pointer to a nsIContent object (as a nsINode pointer)
     28 *  - a pointer to a nsIContent object (a nsIContent as a nsINode pointer) and
     29 *    an index
     30 *
     31 * So we make txXPathNode store a |nsCOMPtr<nsINode>| and a uint32_t for the
     32 * index. To be able to distinguish between the attribute nodes and other nodes
     33 * we store a flag value for the other nodes in the index. To be able to quickly
     34 * cast from the nsINode pointer to a nsIDocument or nsIContent pointer we
     35 * actually use 2 different flag values (see txXPathNode::PositionType).
     36 *
     37 * We provide 2 fast constructors for txXPathNode, one that takes a nsIContent
     38 * and one that takes a nsIDocument, since for those kinds of nodes we can
     39 * simply store the pointer and the relevant flag value. For attribute nodes, or
     40 * if you have just a nsINode pointer, then there is a helper function
     41 * (txXPathNativeNode::createXPathNode) that either picks the right flag value
     42 * or the correct index (for attribute nodes) when creating the txXPathNode.
     43 */
     44 class txXPathNode {
     45 public:
     46  explicit txXPathNode(const txXPathNode& aNode)
     47      : mNode(aNode.mNode), mIndex(aNode.mIndex) {
     48    MOZ_COUNT_CTOR(txXPathNode);
     49  }
     50  txXPathNode(txXPathNode&& aNode)
     51      : mNode(std::move(aNode.mNode)), mIndex(aNode.mIndex) {
     52    MOZ_COUNT_CTOR(txXPathNode);
     53  }
     54 
     55  explicit txXPathNode(mozilla::dom::Document* aDocument)
     56      : mNode(aDocument), mIndex(eDocument) {
     57    MOZ_COUNT_CTOR(txXPathNode);
     58  }
     59  explicit txXPathNode(nsIContent* aContent)
     60      : mNode(aContent), mIndex(eContent) {
     61    MOZ_COUNT_CTOR(txXPathNode);
     62  }
     63 
     64  txXPathNode& operator=(txXPathNode&& aOther) = default;
     65  bool operator==(const txXPathNode& aNode) const;
     66  bool operator!=(const txXPathNode& aNode) const { return !(*this == aNode); }
     67  ~txXPathNode() { MOZ_COUNT_DTOR(txXPathNode); }
     68 
     69  mozilla::dom::Document* OwnerDoc() const { return mNode->OwnerDoc(); }
     70 
     71 private:
     72  friend class txXPathNativeNode;
     73  friend class txXPathNodeUtils;
     74  friend class txXPathTreeWalker;
     75 
     76  txXPathNode(nsINode* aNode, uint32_t aIndex) : mNode(aNode), mIndex(aIndex) {
     77    MOZ_COUNT_CTOR(txXPathNode);
     78  }
     79 
     80  static nsINode* RootOf(nsINode* aNode) { return aNode->SubtreeRoot(); }
     81  nsINode* Root() const { return RootOf(mNode); }
     82 
     83  bool isDocument() const { return mIndex == eDocument; }
     84  bool isContent() const { return mIndex == eContent; }
     85  bool isAttribute() const { return mIndex != eDocument && mIndex != eContent; }
     86 
     87  nsIContent* Content() const {
     88    NS_ASSERTION(isContent() || isAttribute(), "wrong type");
     89    return static_cast<nsIContent*>(mNode.get());
     90  }
     91  mozilla::dom::Document* Document() const {
     92    NS_ASSERTION(isDocument(), "wrong type");
     93    return static_cast<mozilla::dom::Document*>(mNode.get());
     94  }
     95 
     96  enum PositionType : uint32_t {
     97    eDocument = UINT32_MAX,
     98    eContent = eDocument - 1
     99  };
    100 
    101  nsCOMPtr<nsINode> mNode;
    102  uint32_t mIndex;
    103 };
    104 
    105 class txNamespaceManager {
    106 public:
    107  static int32_t getNamespaceID(const nsAString& aNamespaceURI);
    108  static nsresult getNamespaceURI(const int32_t aID, nsAString& aResult);
    109 };
    110 
    111 /* static */
    112 inline int32_t txNamespaceManager::getNamespaceID(
    113    const nsAString& aNamespaceURI) {
    114  int32_t namespaceID = kNameSpaceID_Unknown;
    115  nsNameSpaceManager::GetInstance()->RegisterNameSpace(aNamespaceURI,
    116                                                       namespaceID);
    117  return namespaceID;
    118 }
    119 
    120 /* static */
    121 inline nsresult txNamespaceManager::getNamespaceURI(const int32_t aID,
    122                                                    nsAString& aResult) {
    123  return nsNameSpaceManager::GetInstance()->GetNameSpaceURI(aID, aResult);
    124 }
    125 
    126 inline bool txXPathNode::operator==(const txXPathNode& aNode) const {
    127  return mIndex == aNode.mIndex && mNode == aNode.mNode;
    128 }
    129 
    130 #endif /* txXPathNode_h__ */