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/dom/NodeInfo.h" 16 #include "mozilla/dom/DOMArena.h" 17 #include "mozilla/MruCache.h" 18 #include "nsCOMPtr.h" // for member 19 #include "nsCycleCollectionParticipant.h" // for NS_DECL_CYCLE_* 20 #include "nsTHashMap.h" 21 #include "nsStringFwd.h" 22 23 class nsAtom; 24 class nsIPrincipal; 25 class nsWindowSizes; 26 template <class T> 27 struct already_AddRefed; 28 29 namespace mozilla { 30 namespace dom { 31 class Document; 32 } // namespace dom 33 } // namespace mozilla 34 35 class nsNodeInfoManager final { 36 private: 37 ~nsNodeInfoManager(); 38 39 public: 40 nsNodeInfoManager(); 41 42 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_NATIVE_CLASS(nsNodeInfoManager) 43 44 NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsNodeInfoManager) 45 46 /** 47 * Initialize the nodeinfo manager with a document. 48 */ 49 nsresult Init(mozilla::dom::Document*); 50 51 /** 52 * Release the reference to the document, this will be called when 53 * the document is going away. 54 */ 55 void DropDocumentReference(); 56 57 /** 58 * Methods for creating nodeinfo's from atoms and/or strings. 59 */ 60 already_AddRefed<mozilla::dom::NodeInfo> GetNodeInfo( 61 nsAtom* aName, nsAtom* aPrefix, int32_t aNamespaceID, uint16_t aNodeType, 62 nsAtom* aExtraName = nullptr); 63 nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix, 64 int32_t aNamespaceID, uint16_t aNodeType, 65 mozilla::dom::NodeInfo** aNodeInfo); 66 nsresult GetNodeInfo(const nsAString& aName, nsAtom* aPrefix, 67 const nsAString& aNamespaceURI, uint16_t aNodeType, 68 mozilla::dom::NodeInfo** aNodeInfo); 69 70 /** 71 * Returns the nodeinfo for text nodes. Can return null if OOM. 72 */ 73 already_AddRefed<mozilla::dom::NodeInfo> GetTextNodeInfo(); 74 75 /** 76 * Returns the nodeinfo for comment nodes. Can return null if OOM. 77 */ 78 already_AddRefed<mozilla::dom::NodeInfo> GetCommentNodeInfo(); 79 80 /** 81 * Returns the nodeinfo for the document node. Can return null if OOM. 82 */ 83 already_AddRefed<mozilla::dom::NodeInfo> GetDocumentNodeInfo(); 84 85 /** 86 * Retrieve a pointer to the document that owns this node info 87 * manager. 88 */ GetDocument()89 mozilla::dom::Document* GetDocument() const { return mDocument; } 90 91 /** 92 * Gets the principal of the document this nodeinfo manager belongs to. 93 */ DocumentPrincipal()94 nsIPrincipal* DocumentPrincipal() const { 95 NS_ASSERTION(mPrincipal, "How'd that happen?"); 96 return mPrincipal; 97 } 98 99 void RemoveNodeInfo(mozilla::dom::NodeInfo* aNodeInfo); 100 101 /** 102 * Returns true if SVG nodes in this document have real SVG semantics. 103 */ SVGEnabled()104 bool SVGEnabled() { 105 return mSVGEnabled.valueOrFrom([this] { return InternalSVGEnabled(); }); 106 } 107 108 /** 109 * Returns true if MathML nodes in this document have real MathML semantics. 110 */ MathMLEnabled()111 bool MathMLEnabled() { 112 return mMathMLEnabled.valueOrFrom( 113 [this] { return InternalMathMLEnabled(); }); 114 } 115 GetArenaAllocator()116 mozilla::dom::DOMArena* GetArenaAllocator() { return mArena; } 117 void SetArenaAllocator(mozilla::dom::DOMArena* aArena); 118 119 void* Allocate(size_t aSize); 120 Free(void * aPtr)121 void Free(void* aPtr) { free(aPtr); } 122 HasAllocated()123 bool HasAllocated() { return mHasAllocated; } 124 125 void AddSizeOfIncludingThis(nsWindowSizes& aSizes) const; 126 127 protected: 128 friend class mozilla::dom::Document; 129 friend class nsXULPrototypeDocument; 130 131 /** 132 * Sets the principal of the document this nodeinfo manager belongs to. 133 */ 134 void SetDocumentPrincipal(nsIPrincipal* aPrincipal); 135 136 private: 137 bool InternalSVGEnabled(); 138 bool InternalMathMLEnabled(); 139 140 class NodeInfoInnerKey 141 : public nsPtrHashKey<mozilla::dom::NodeInfo::NodeInfoInner> { 142 public: NodeInfoInnerKey(KeyTypePointer aKey)143 explicit NodeInfoInnerKey(KeyTypePointer aKey) : nsPtrHashKey(aKey) {} 144 NodeInfoInnerKey(NodeInfoInnerKey&&) = default; 145 ~NodeInfoInnerKey() = default; KeyEquals(KeyTypePointer aKey)146 bool KeyEquals(KeyTypePointer aKey) const { return *mKey == *aKey; } HashKey(KeyTypePointer aKey)147 static PLDHashNumber HashKey(KeyTypePointer aKey) { return aKey->Hash(); } 148 }; 149 150 struct NodeInfoCache 151 : public mozilla::MruCache<mozilla::dom::NodeInfo::NodeInfoInner, 152 mozilla::dom::NodeInfo*, NodeInfoCache> { HashNodeInfoCache153 static mozilla::HashNumber Hash( 154 const mozilla::dom::NodeInfo::NodeInfoInner& aKey) { 155 return aKey.Hash(); 156 } MatchNodeInfoCache157 static bool Match(const mozilla::dom::NodeInfo::NodeInfoInner& aKey, 158 const mozilla::dom::NodeInfo* aVal) { 159 return aKey == aVal->mInner; 160 } 161 }; 162 163 nsTHashMap<NodeInfoInnerKey, mozilla::dom::NodeInfo*> mNodeInfoHash; 164 mozilla::dom::Document* MOZ_NON_OWNING_REF mDocument; // WEAK 165 uint32_t mNonDocumentNodeInfos; 166 nsCOMPtr<nsIPrincipal> mPrincipal; // Never null after Init() succeeds. 167 nsCOMPtr<nsIPrincipal> mDefaultPrincipal; // Never null after Init() succeeds 168 mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF 169 mTextNodeInfo; // WEAK to avoid circular ownership 170 mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF 171 mCommentNodeInfo; // WEAK to avoid circular ownership 172 mozilla::dom::NodeInfo* MOZ_NON_OWNING_REF 173 mDocumentNodeInfo; // WEAK to avoid circular ownership 174 NodeInfoCache mRecentlyUsedNodeInfos; 175 mozilla::Maybe<bool> mSVGEnabled; // Lazily initialized. 176 mozilla::Maybe<bool> mMathMLEnabled; // Lazily initialized. 177 178 // For dom_arena_allocator_enabled 179 RefPtr<mozilla::dom::DOMArena> mArena; 180 bool mHasAllocated = false; 181 }; 182 183 #endif /* nsNodeInfoManager_h___ */ 184