nsNodeInfoManager.h (6021B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* 8 * A class for handing out nodeinfos and ensuring sharing of them as needed. 9 */ 10 11 #ifndef nsNodeInfoManager_h___ 12 #define nsNodeInfoManager_h___ 13 14 #include "mozilla/Attributes.h" // for final 15 #include "mozilla/MruCache.h" 16 #include "mozilla/dom/DOMArena.h" 17 #include "mozilla/dom/NodeInfo.h" 18 #include "nsCOMPtr.h" // for member 19 #include "nsCycleCollectionParticipant.h" // for NS_DECL_CYCLE_* 20 #include "nsStringFwd.h" 21 #include "nsTHashMap.h" 22 23 class nsAtom; 24 class nsIPrincipal; 25 class nsWindowSizes; 26 template <class T> 27 struct already_AddRefed; 28 29 namespace mozilla::dom { 30 class Document; 31 } // namespace mozilla::dom 32 33 class nsNodeInfoManager final { 34 private: 35 ~nsNodeInfoManager(); 36 37 public: 38 explicit nsNodeInfoManager(mozilla::dom::Document* aDocument, 39 nsIPrincipal* aPrincipal); 40 41 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS(nsNodeInfoManager) 42 43 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsNodeInfoManager) 44 45 /** 46 * Release the reference to the document, this will be called when 47 * the document is going away. 48 */ 49 void DropDocumentReference(); 50 51 /** 52 * Methods for creating nodeinfo's from atoms and/or strings. 53 */ 54 already_AddRefed<mozilla::dom::NodeInfo> GetNodeInfo( 55 nsAtom* aName, nsAtom* aPrefix, int32_t aNamespaceID, uint16_t aNodeType, 56 nsAtom* aExtraName = nullptr); 57 nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix, 58 int32_t aNamespaceID, uint16_t aNodeType, 59 mozilla::dom::NodeInfo** aNodeInfo); 60 nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix, 61 const nsAString& aNamespaceURI, uint16_t aNodeType, 62 mozilla::dom::NodeInfo** aNodeInfo); 63 64 /** 65 * Returns the nodeinfo for text nodes. Can return null if OOM. 66 */ 67 already_AddRefed<mozilla::dom::NodeInfo> GetTextNodeInfo(); 68 69 /** 70 * Returns the nodeinfo for comment nodes. Can return null if OOM. 71 */ 72 already_AddRefed<mozilla::dom::NodeInfo> GetCommentNodeInfo(); 73 74 /** 75 * Returns the nodeinfo for the document node. Can return null if OOM. 76 */ 77 already_AddRefed<mozilla::dom::NodeInfo> GetDocumentNodeInfo(); 78 79 /** 80 * Retrieve a pointer to the document that owns this node info 81 * manager. 82 */ 83 mozilla::dom::Document* GetDocument() const { return mDocument; } 84 85 /** 86 * Gets the principal of the document this nodeinfo manager belongs to. 87 */ 88 nsIPrincipal* DocumentPrincipal() const { 89 NS_ASSERTION(mPrincipal, "How'd that happen?"); 90 return mPrincipal; 91 } 92 93 void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo); 94 95 /** 96 * Returns true if SVG nodes in this document have real SVG semantics. 97 */ 98 bool SVGEnabled() { 99 return mSVGEnabled.valueOrFrom([this] { return InternalSVGEnabled(); }); 100 } 101 102 /** 103 * Returns true if MathML nodes in this document have real MathML semantics. 104 */ 105 bool MathMLEnabled() { 106 return mMathMLEnabled.valueOrFrom( 107 [this] { return InternalMathMLEnabled(); }); 108 } 109 110 mozilla::dom::DOMArena* GetArenaAllocator() { return mArena; } 111 void SetArenaAllocator(mozilla::dom::DOMArena* aArena); 112 113 void* Allocate(size_t aSize); 114 115 void Free(void* aPtr) { free(aPtr); } 116 117 bool HasAllocated() { return mHasAllocated; } 118 119 void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const; 120 121 protected: 122 friend class mozilla::dom::Document; 123 friend class nsXULPrototypeDocument; 124 125 /** 126 * Sets the principal of the document this nodeinfo manager belongs to. 127 */ 128 void SetDocumentPrincipal(nsIPrincipal* aPrincipal); 129 130 private: 131 bool InternalSVGEnabled(); 132 bool InternalMathMLEnabled(); 133 134 class NodeInfoInnerKey 135 : public nsPtrHashKey<mozilla::dom::NodeInfo::NodeInfoInner> { 136 public: 137 explicit NodeInfoInnerKey(KeyTypePointer aKey) : nsPtrHashKey(aKey) {} 138 NodeInfoInnerKey(NodeInfoInnerKey&&) = default; 139 ~NodeInfoInnerKey() = default; 140 bool KeyEquals(KeyTypePointer aKey) const { return *mKey == *aKey; } 141 static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); } 142 }; 143 144 struct NodeInfoCache 145 : public mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, 146 mozilla::dom::NodeInfo*, NodeInfoCache> { 147 static mozilla::HashNumber Hash( 148 const mozilla::dom::NodeInfo::NodeInfoInner& aKey) { 149 return aKey.Hash(); 150 } 151 static bool Match(const mozilla::dom::NodeInfo::NodeInfoInner& aKey, 152 const mozilla::dom::NodeInfo* aVal) { 153 return (aKey.Hash() == aVal->mInner.Hash()) && (aKey == aVal->mInner); 154 } 155 }; 156 157 nsTHashMap<NodeInfoInnerKey, mozilla::dom::NodeInfo*> mNodeInfoHash; 158 mozilla::dom::Document* MOZ_NON_OWNING_REF mDocument; // WEAK 159 uint32_t mNonDocumentNodeInfos; 160 161 // Note: it's important that mPrincipal is declared before mDefaultPrincipal, 162 // since the latter is initialized to the value of the former in the 163 // constructor's init list: 164 nsCOMPtr<nsIPrincipal> mPrincipal; // Never null 165 nsCOMPtr<nsIPrincipal> mDefaultPrincipal; // Never null 166 167 mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF 168 mTextNodeInfo; // WEAK to avoid circular ownership 169 mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF 170 mCommentNodeInfo; // WEAK to avoid circular ownership 171 mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF 172 mDocumentNodeInfo; // WEAK to avoid circular ownership 173 NodeInfoCache mRecentlyUsedNodeInfos; 174 mozilla::Maybe<bool> mSVGEnabled; // Lazily initialized. 175 mozilla::Maybe<bool> mMathMLEnabled; // Lazily initialized. 176 177 // For dom_arena_allocator_enabled 178 RefPtr<mozilla::dom::DOMArena> mArena; 179 bool mHasAllocated = false; 180 }; 181 182 #endif /* nsNodeInfoManager_h___ */