DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */

/*
 * A class for handing out nodeinfos and ensuring sharing of them as needed.
 */

#ifndef nsNodeInfoManager_h___
#define nsNodeInfoManager_h___

#include "mozilla/Attributes.h"  // for final
#include "mozilla/dom/NodeInfo.h"
#include "nsCOMPtr.h"                      // for member
#include "nsCycleCollectionParticipant.h"  // for NS_DECL_CYCLE_*
#include "nsDataHashtable.h"
#include "nsStringFwd.h"

class nsBindingManager;
class nsAtom;
class nsIDocument;
class nsIDOMDocumentType;
class nsIPrincipal;
class nsWindowSizes;
struct PLHashEntry;
struct PLHashTable;
template <class T>
struct already_AddRefed;

#define RECENTLY_USED_NODEINFOS_SIZE 31

class nsNodeInfoManager final {
 private:
  ~nsNodeInfoManager();

 public:
  nsNodeInfoManager();

  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS(nsNodeInfoManager)

  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsNodeInfoManager)

  /**
   * Initialize the nodeinfo manager with a document.
   */
  nsresult Init(nsIDocument* aDocument);

  /**
   * Release the reference to the document, this will be called when
   * the document is going away.
   */
  void DropDocumentReference();

  /**
   * Methods for creating nodeinfo's from atoms and/or strings.
   */
  already_AddRefed<mozilla::dom::NodeInfo> GetNodeInfo(
      nsAtom* aName, nsAtom* aPrefix, int32_t aNamespaceID, uint16_t aNodeType,
      nsAtom* aExtraName = nullptr);
  nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix,
                       int32_t aNamespaceID, uint16_t aNodeType,
                       mozilla::dom::NodeInfo** aNodeInfo);
  nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix,
                       const nsAString& aNamespaceURI, uint16_t aNodeType,
                       mozilla::dom::NodeInfo** aNodeInfo);

  /**
   * Returns the nodeinfo for text nodes. Can return null if OOM.
   */
  already_AddRefed<mozilla::dom::NodeInfo> GetTextNodeInfo();

  /**
   * Returns the nodeinfo for comment nodes. Can return null if OOM.
   */
  already_AddRefed<mozilla::dom::NodeInfo> GetCommentNodeInfo();

  /**
   * Returns the nodeinfo for the document node. Can return null if OOM.
   */
  already_AddRefed<mozilla::dom::NodeInfo> GetDocumentNodeInfo();

  /**
   * Retrieve a pointer to the document that owns this node info
   * manager.
   */
  nsIDocument* GetDocument() const { return mDocument; }

  /**
   * Gets the principal of the document this nodeinfo manager belongs to.
   */
  nsIPrincipal* DocumentPrincipal() const {
    NS_ASSERTION(mPrincipal, "How'd that happen?");
    return mPrincipal;
  }

  void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo);

  nsBindingManager* GetBindingManager() const { return mBindingManager; }

  enum Tri { eTriUnset = 0, eTriFalse, eTriTrue };

  /**
   * Returns true if SVG nodes in this document have real SVG semantics.
   */
  bool SVGEnabled() {
    return mSVGEnabled == eTriTrue
               ? true
               : mSVGEnabled == eTriFalse ? false : InternalSVGEnabled();
  }

  /**
   * Returns true if MathML nodes in this document have real MathML semantics.
   */
  bool MathMLEnabled() {
    return mMathMLEnabled == eTriTrue
               ? true
               : mMathMLEnabled == eTriFalse ? false : InternalMathMLEnabled();
  }

  void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const;

 protected:
  friend class nsDocument;
  friend class nsXULPrototypeDocument;
  friend nsresult NS_NewDOMDocumentType(nsIDOMDocumentType**,
                                        nsNodeInfoManager*, nsAtom*,
                                        const nsAString&, const nsAString&,
                                        const nsAString&);

  /**
   * Sets the principal of the document this nodeinfo manager belongs to.
   */
  void SetDocumentPrincipal(nsIPrincipal* aPrincipal);

 private:
  bool InternalSVGEnabled();
  bool InternalMathMLEnabled();

  class NodeInfoInnerKey
      : public nsPtrHashKey<mozilla::dom::NodeInfo::NodeInfoInner> {
   public:
    explicit NodeInfoInnerKey(KeyTypePointer aKey) : nsPtrHashKey(aKey) {}
    ~NodeInfoInnerKey() = default;
    bool KeyEquals(KeyTypePointer aKey) const { return *mKey == *aKey; }
    static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); }
  };

  nsDataHashtable<NodeInfoInnerKey, mozilla::dom::NodeInfo*> mNodeInfoHash;
  nsIDocument* MOZ_NON_OWNING_REF mDocument;  // WEAK
  uint32_t mNonDocumentNodeInfos;
  nsCOMPtr<nsIPrincipal> mPrincipal;  // Never null after Init() succeeds.
  nsCOMPtr<nsIPrincipal> mDefaultPrincipal;  // Never null after Init() succeeds
  mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
      mTextNodeInfo;  // WEAK to avoid circular ownership
  mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
      mCommentNodeInfo;  // WEAK to avoid circular ownership
  mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF
      mDocumentNodeInfo;  // WEAK to avoid circular ownership
  RefPtr<nsBindingManager> mBindingManager;
  mozilla::dom::NodeInfo* mRecentlyUsedNodeInfos[RECENTLY_USED_NODEINFOS_SIZE];
  Tri mSVGEnabled;
  Tri mMathMLEnabled;
};

#endif /* nsNodeInfoManager_h___ */