DocManager.h (5336B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_a11_DocManager_h_ 6 #define mozilla_a11_DocManager_h_ 7 8 #include "mozilla/ClearOnShutdown.h" 9 #include "nsIDOMEventListener.h" 10 #include "nsRefPtrHashtable.h" 11 #include "nsIWebProgressListener.h" 12 #include "nsWeakReference.h" 13 #include "mozilla/StaticPtr.h" 14 #include "nsINode.h" 15 16 namespace mozilla::dom { 17 class Document; 18 } 19 20 namespace mozilla { 21 class PresShell; 22 23 namespace a11y { 24 25 class LocalAccessible; 26 class DocAccessible; 27 class xpcAccessibleDocument; 28 class DocAccessibleParent; 29 30 /** 31 * Manage the document accessible life cycle. 32 */ 33 class DocManager : public nsIWebProgressListener, 34 public nsIDOMEventListener, 35 public nsSupportsWeakReference { 36 public: 37 NS_DECL_THREADSAFE_ISUPPORTS 38 NS_DECL_NSIWEBPROGRESSLISTENER 39 NS_DECL_NSIDOMEVENTLISTENER 40 41 /** 42 * Return document accessible for the given DOM node. 43 */ 44 DocAccessible* GetDocAccessible(dom::Document* aDocument); 45 46 /** 47 * Return document accessible for the given presshell. 48 */ 49 DocAccessible* GetDocAccessible(const PresShell* aPresShell); 50 51 /** 52 * Search through all document accessibles for an accessible with the given 53 * unique id. 54 */ 55 LocalAccessible* FindAccessibleInCache(nsINode* aNode) const; 56 57 /** 58 * Called by document accessible when it gets shutdown. 59 */ 60 void NotifyOfDocumentShutdown(DocAccessible* aDocument, 61 dom::Document* aDOMDocument); 62 63 void RemoveFromXPCDocumentCache(DocAccessible* aDocument); 64 65 /** 66 * Return XPCOM accessible document. 67 */ 68 xpcAccessibleDocument* GetXPCDocument(DocAccessible* aDocument); 69 xpcAccessibleDocument* GetCachedXPCDocument(DocAccessible* aDocument) const { 70 return mXPCDocumentCache.GetWeak(aDocument); 71 } 72 73 /* 74 * Notification that a top level document in a content process has gone away. 75 */ 76 static void RemoteDocShutdown(DocAccessibleParent* aDoc) { 77 DebugOnly<bool> result = sRemoteDocuments->RemoveElement(aDoc); 78 MOZ_ASSERT(result, "Why didn't we find the document!"); 79 } 80 81 /* 82 * Notify of a new top level document in a content process. 83 */ 84 static void RemoteDocAdded(DocAccessibleParent* aDoc); 85 86 static const nsTArray<DocAccessibleParent*>* TopLevelRemoteDocs() { 87 return sRemoteDocuments; 88 } 89 90 /** 91 * Remove the xpc document for a remote document if there is one. 92 */ 93 static void NotifyOfRemoteDocShutdown(DocAccessibleParent* adoc); 94 95 static void RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc); 96 97 /** 98 * Get a XPC document for a remote document. 99 */ 100 static xpcAccessibleDocument* GetXPCDocument(DocAccessibleParent* aDoc); 101 static xpcAccessibleDocument* GetCachedXPCDocument( 102 const DocAccessibleParent* aDoc) { 103 return sRemoteXPCDocumentCache ? sRemoteXPCDocumentCache->GetWeak(aDoc) 104 : nullptr; 105 } 106 107 #ifdef DEBUG 108 bool IsProcessingRefreshDriverNotification() const; 109 #endif 110 111 protected: 112 DocManager(); 113 virtual ~DocManager() = default; 114 115 /** 116 * Initialize the manager. 117 */ 118 bool Init(); 119 120 /** 121 * Shutdown the manager. 122 */ 123 void Shutdown(); 124 125 bool HasXPCDocuments() { 126 return mXPCDocumentCache.Count() > 0 || 127 (sRemoteXPCDocumentCache && sRemoteXPCDocumentCache->Count() > 0); 128 } 129 130 private: 131 DocManager(const DocManager&); 132 DocManager& operator=(const DocManager&); 133 134 private: 135 /** 136 * Create an accessible document if it was't created and fire accessibility 137 * events if needed. 138 * 139 * @param aDocument [in] loaded DOM document 140 * @param aLoadEventType [in] specifies the event type to fire load event, 141 * if 0 then no event is fired 142 */ 143 void HandleDOMDocumentLoad(dom::Document* aDocument, uint32_t aLoadEventType); 144 145 /** 146 * Add/remove 'pagehide' and 'DOMContentLoaded' event listeners. 147 */ 148 void AddListeners(dom::Document* aDocument, bool aAddPageShowListener); 149 void RemoveListeners(dom::Document* aDocument); 150 151 /** 152 * Create document or root accessible. 153 */ 154 DocAccessible* CreateDocOrRootAccessible(dom::Document* aDocument); 155 156 /** 157 * Clear the cache and shutdown the document accessibles. 158 */ 159 void ClearDocCache(); 160 161 protected: 162 typedef nsRefPtrHashtable<nsPtrHashKey<const dom::Document>, DocAccessible> 163 DocAccessibleHashtable; 164 DocAccessibleHashtable mDocAccessibleCache; 165 166 private: 167 typedef nsRefPtrHashtable<nsPtrHashKey<const DocAccessible>, 168 xpcAccessibleDocument> 169 XPCDocumentHashtable; 170 XPCDocumentHashtable mXPCDocumentCache; 171 static StaticAutoPtr<nsRefPtrHashtable< 172 nsPtrHashKey<const DocAccessibleParent>, xpcAccessibleDocument>> 173 sRemoteXPCDocumentCache; 174 175 /* 176 * The list of remote top level documents. 177 */ 178 static StaticAutoPtr<nsTArray<DocAccessibleParent*>> sRemoteDocuments; 179 }; 180 181 /** 182 * Return the existing document accessible for the document if any. 183 * Note this returns the doc accessible for the primary pres shell if there is 184 * more than one. 185 */ 186 DocAccessible* GetExistingDocAccessible(const dom::Document* aDocument); 187 188 } // namespace a11y 189 } // namespace mozilla 190 191 #endif // mozilla_a11_DocManager_h_