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