/src/mozilla-central/accessible/generic/DocAccessible.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | #ifndef mozilla_a11y_DocAccessible_h__ |
7 | | #define mozilla_a11y_DocAccessible_h__ |
8 | | |
9 | | #include "nsIAccessiblePivot.h" |
10 | | |
11 | | #include "HyperTextAccessibleWrap.h" |
12 | | #include "AccEvent.h" |
13 | | |
14 | | #include "nsAutoPtr.h" |
15 | | #include "nsClassHashtable.h" |
16 | | #include "nsDataHashtable.h" |
17 | | #include "nsIDocument.h" |
18 | | #include "nsIDocumentObserver.h" |
19 | | #include "nsIObserver.h" |
20 | | #include "nsIScrollPositionListener.h" |
21 | | #include "nsITimer.h" |
22 | | #include "nsIWeakReference.h" |
23 | | |
24 | | class nsAccessiblePivot; |
25 | | |
26 | | const uint32_t kDefaultCacheLength = 128; |
27 | | |
28 | | namespace mozilla { |
29 | | |
30 | | class TextEditor; |
31 | | |
32 | | namespace a11y { |
33 | | |
34 | | class DocManager; |
35 | | class NotificationController; |
36 | | class DocAccessibleChild; |
37 | | class RelatedAccIterator; |
38 | | template<class Class, class ... Args> |
39 | | class TNotification; |
40 | | |
41 | | class DocAccessible : public HyperTextAccessibleWrap, |
42 | | public nsIDocumentObserver, |
43 | | public nsIObserver, |
44 | | public nsIScrollPositionListener, |
45 | | public nsSupportsWeakReference, |
46 | | public nsIAccessiblePivotObserver |
47 | | { |
48 | | NS_DECL_ISUPPORTS_INHERITED |
49 | | NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocAccessible, Accessible) |
50 | | |
51 | | NS_DECL_NSIOBSERVER |
52 | | NS_DECL_NSIACCESSIBLEPIVOTOBSERVER |
53 | | |
54 | | public: |
55 | | |
56 | | DocAccessible(nsIDocument* aDocument, nsIPresShell* aPresShell); |
57 | | |
58 | | // nsIScrollPositionListener |
59 | 0 | virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) override {} |
60 | | virtual void ScrollPositionDidChange(nscoord aX, nscoord aY) override; |
61 | | |
62 | | // nsIDocumentObserver |
63 | | NS_DECL_NSIDOCUMENTOBSERVER |
64 | | |
65 | | // Accessible |
66 | | virtual void Init(); |
67 | | virtual void Shutdown() override; |
68 | | virtual nsIFrame* GetFrame() const override; |
69 | 0 | virtual nsINode* GetNode() const override { return mDocumentNode; } |
70 | | nsIDocument* DocumentNode() const { return mDocumentNode; } |
71 | | |
72 | | virtual mozilla::a11y::ENameValueFlag Name(nsString& aName) const override; |
73 | | virtual void Description(nsString& aDescription) override; |
74 | | virtual Accessible* FocusedChild() override; |
75 | | virtual mozilla::a11y::role NativeRole() const override; |
76 | | virtual uint64_t NativeState() const override; |
77 | | virtual uint64_t NativeInteractiveState() const override; |
78 | | virtual bool NativelyUnavailable() const override; |
79 | | virtual void ApplyARIAState(uint64_t* aState) const override; |
80 | | virtual already_AddRefed<nsIPersistentProperties> Attributes() override; |
81 | | |
82 | | virtual void TakeFocus() const override; |
83 | | |
84 | | #ifdef A11Y_LOG |
85 | | virtual nsresult HandleAccEvent(AccEvent* aEvent) override; |
86 | | #endif |
87 | | |
88 | | virtual nsRect RelativeBounds(nsIFrame** aRelativeFrame) const override; |
89 | | |
90 | | // HyperTextAccessible |
91 | | virtual already_AddRefed<TextEditor> GetEditor() const override; |
92 | | |
93 | | // DocAccessible |
94 | | |
95 | | /** |
96 | | * Return document URL. |
97 | | */ |
98 | | void URL(nsAString& aURL) const; |
99 | | |
100 | | /** |
101 | | * Return DOM document title. |
102 | | */ |
103 | | void Title(nsString& aTitle) const { mDocumentNode->GetTitle(aTitle); } |
104 | | |
105 | | /** |
106 | | * Return DOM document mime type. |
107 | | */ |
108 | 0 | void MimeType(nsAString& aType) const { mDocumentNode->GetContentType(aType); } |
109 | | |
110 | | /** |
111 | | * Return DOM document type. |
112 | | */ |
113 | | void DocType(nsAString& aType) const; |
114 | | |
115 | | /** |
116 | | * Return virtual cursor associated with the document. |
117 | | */ |
118 | | nsIAccessiblePivot* VirtualCursor(); |
119 | | |
120 | | /** |
121 | | * Return presentation shell for this document accessible. |
122 | | */ |
123 | 0 | nsIPresShell* PresShell() const { return mPresShell; } |
124 | | |
125 | | /** |
126 | | * Return the presentation shell's context. |
127 | | */ |
128 | | nsPresContext* PresContext() const { return mPresShell->GetPresContext(); } |
129 | | |
130 | | /** |
131 | | * Return true if associated DOM document was loaded and isn't unloading. |
132 | | */ |
133 | | bool IsContentLoaded() const |
134 | | { |
135 | | // eDOMLoaded flag check is used for error pages as workaround to make this |
136 | | // method return correct result since error pages do not receive 'pageshow' |
137 | | // event and as consequence nsIDocument::IsShowing() returns false. |
138 | | return mDocumentNode && mDocumentNode->IsVisible() && |
139 | | (mDocumentNode->IsShowing() || HasLoadState(eDOMLoaded)); |
140 | | } |
141 | | |
142 | | bool IsHidden() const |
143 | | { |
144 | | return mDocumentNode->Hidden(); |
145 | | } |
146 | | |
147 | | /** |
148 | | * Document load states. |
149 | | */ |
150 | | enum LoadState { |
151 | | // initial tree construction is pending |
152 | | eTreeConstructionPending = 0, |
153 | | // initial tree construction done |
154 | | eTreeConstructed = 1, |
155 | | // DOM document is loaded. |
156 | | eDOMLoaded = 1 << 1, |
157 | | // document is ready |
158 | | eReady = eTreeConstructed | eDOMLoaded, |
159 | | // document and all its subdocuments are ready |
160 | | eCompletelyLoaded = eReady | 1 << 2 |
161 | | }; |
162 | | |
163 | | /** |
164 | | * Return true if the document has given document state. |
165 | | */ |
166 | | bool HasLoadState(LoadState aState) const |
167 | | { return (mLoadState & static_cast<uint32_t>(aState)) == |
168 | | static_cast<uint32_t>(aState); } |
169 | | |
170 | | /** |
171 | | * Return a native window handler or pointer depending on platform. |
172 | | */ |
173 | | virtual void* GetNativeWindow() const; |
174 | | |
175 | | /** |
176 | | * Return the parent document. |
177 | | */ |
178 | | DocAccessible* ParentDocument() const |
179 | | { return mParent ? mParent->Document() : nullptr; } |
180 | | |
181 | | /** |
182 | | * Return the child document count. |
183 | | */ |
184 | | uint32_t ChildDocumentCount() const |
185 | | { return mChildDocuments.Length(); } |
186 | | |
187 | | /** |
188 | | * Return the child document at the given index. |
189 | | */ |
190 | | DocAccessible* GetChildDocumentAt(uint32_t aIndex) const |
191 | | { return mChildDocuments.SafeElementAt(aIndex, nullptr); } |
192 | | |
193 | | /** |
194 | | * Fire accessible event asynchronously. |
195 | | */ |
196 | | void FireDelayedEvent(AccEvent* aEvent); |
197 | | void FireDelayedEvent(uint32_t aEventType, Accessible* aTarget); |
198 | | void FireEventsOnInsertion(Accessible* aContainer); |
199 | | |
200 | | /** |
201 | | * Fire value change event on the given accessible if applicable. |
202 | | */ |
203 | | void MaybeNotifyOfValueChange(Accessible* aAccessible); |
204 | | |
205 | | /** |
206 | | * Get/set the anchor jump. |
207 | | */ |
208 | | Accessible* AnchorJump() |
209 | | { return GetAccessibleOrContainer(mAnchorJumpElm); } |
210 | | |
211 | | void SetAnchorJump(nsIContent* aTargetNode) |
212 | | { mAnchorJumpElm = aTargetNode; } |
213 | | |
214 | | /** |
215 | | * Bind the child document to the tree. |
216 | | */ |
217 | | void BindChildDocument(DocAccessible* aDocument); |
218 | | |
219 | | /** |
220 | | * Process the generic notification. |
221 | | * |
222 | | * @note The caller must guarantee that the given instance still exists when |
223 | | * notification is processed. |
224 | | * @see NotificationController::HandleNotification |
225 | | */ |
226 | | template<class Class, class Arg> |
227 | | void HandleNotification(Class* aInstance, |
228 | | typename TNotification<Class, Arg>::Callback aMethod, |
229 | | Arg* aArg); |
230 | | |
231 | | /** |
232 | | * Return the cached accessible by the given DOM node if it's in subtree of |
233 | | * this document accessible or the document accessible itself, otherwise null. |
234 | | * |
235 | | * @return the accessible object |
236 | | */ |
237 | | Accessible* GetAccessible(nsINode* aNode) const |
238 | 0 | { |
239 | 0 | return aNode == mDocumentNode ? |
240 | 0 | const_cast<DocAccessible*>(this) : mNodeToAccessibleMap.Get(aNode); |
241 | 0 | } |
242 | | |
243 | | /** |
244 | | * Return an accessible for the given node even if the node is not in |
245 | | * document's node map cache (like HTML area element). |
246 | | * |
247 | | * XXX: it should be really merged with GetAccessible(). |
248 | | */ |
249 | | Accessible* GetAccessibleEvenIfNotInMap(nsINode* aNode) const; |
250 | | Accessible* GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const; |
251 | | |
252 | | /** |
253 | | * Return whether the given DOM node has an accessible or not. |
254 | | */ |
255 | | bool HasAccessible(nsINode* aNode) const |
256 | | { return GetAccessible(aNode); } |
257 | | |
258 | | /** |
259 | | * Return the cached accessible by the given unique ID within this document. |
260 | | * |
261 | | * @note the unique ID matches with the uniqueID() of Accessible |
262 | | * |
263 | | * @param aUniqueID [in] the unique ID used to cache the node. |
264 | | */ |
265 | | Accessible* GetAccessibleByUniqueID(void* aUniqueID) |
266 | | { |
267 | | return UniqueID() == aUniqueID ? |
268 | | this : mAccessibleCache.GetWeak(aUniqueID); |
269 | | } |
270 | | |
271 | | /** |
272 | | * Return the cached accessible by the given unique ID looking through |
273 | | * this and nested documents. |
274 | | */ |
275 | | Accessible* GetAccessibleByUniqueIDInSubtree(void* aUniqueID); |
276 | | |
277 | | /** |
278 | | * Return an accessible for the given DOM node or container accessible if |
279 | | * the node is not accessible. |
280 | | */ |
281 | | enum { |
282 | | eIgnoreARIAHidden = 0, |
283 | | eNoContainerIfARIAHidden = 1 |
284 | | }; |
285 | | Accessible* GetAccessibleOrContainer(nsINode* aNode, |
286 | | int aARIAHiddenFlag = eIgnoreARIAHidden) const; |
287 | | |
288 | | /** |
289 | | * Return a container accessible for the given DOM node. |
290 | | */ |
291 | | Accessible* GetContainerAccessible(nsINode* aNode) const |
292 | | { |
293 | | return aNode ? GetAccessibleOrContainer(aNode->GetParentNode()) : nullptr; |
294 | | } |
295 | | |
296 | | /** |
297 | | * Return an accessible for the given node if any, or an immediate accessible |
298 | | * container for it. |
299 | | */ |
300 | | Accessible* AccessibleOrTrueContainer(nsINode* aNode, |
301 | | int aARIAHiddenFlag = eIgnoreARIAHidden) const; |
302 | | |
303 | | /** |
304 | | * Return an accessible for the given node or its first accessible descendant. |
305 | | */ |
306 | | Accessible* GetAccessibleOrDescendant(nsINode* aNode) const; |
307 | | |
308 | | /** |
309 | | * Returns aria-owns seized child at the given index. |
310 | | */ |
311 | | Accessible* ARIAOwnedAt(Accessible* aParent, uint32_t aIndex) const |
312 | | { |
313 | | nsTArray<RefPtr<Accessible> >* children = mARIAOwnsHash.Get(aParent); |
314 | | if (children) { |
315 | | return children->SafeElementAt(aIndex); |
316 | | } |
317 | | return nullptr; |
318 | | } |
319 | | uint32_t ARIAOwnedCount(Accessible* aParent) const |
320 | | { |
321 | | nsTArray<RefPtr<Accessible> >* children = mARIAOwnsHash.Get(aParent); |
322 | | return children ? children->Length() : 0; |
323 | | } |
324 | | |
325 | | /** |
326 | | * Return true if the given ID is referred by relation attribute. |
327 | | * |
328 | | * @note Different elements may share the same ID if they are hosted inside |
329 | | * XBL bindings. Be careful the result of this method may be senseless |
330 | | * while it's called for XUL elements (where XBL is used widely). |
331 | | */ |
332 | | bool IsDependentID(const nsAString& aID) const |
333 | | { return mDependentIDsHash.Get(aID, nullptr); } |
334 | | |
335 | | /** |
336 | | * Initialize the newly created accessible and put it into document caches. |
337 | | * |
338 | | * @param aAccessible [in] created accessible |
339 | | * @param aRoleMapEntry [in] the role map entry role the ARIA role or nullptr |
340 | | * if none |
341 | | */ |
342 | | void BindToDocument(Accessible* aAccessible, |
343 | | const nsRoleMapEntry* aRoleMapEntry); |
344 | | |
345 | | /** |
346 | | * Remove from document and shutdown the given accessible. |
347 | | */ |
348 | | void UnbindFromDocument(Accessible* aAccessible); |
349 | | |
350 | | /** |
351 | | * Notify the document accessible that content was inserted. |
352 | | */ |
353 | | void ContentInserted(nsIContent* aContainerNode, |
354 | | nsIContent* aStartChildNode, |
355 | | nsIContent* aEndChildNode); |
356 | | |
357 | | /** |
358 | | * Update the tree on content removal. |
359 | | */ |
360 | | void ContentRemoved(Accessible* aAccessible); |
361 | | void ContentRemoved(nsIContent* aContentNode); |
362 | | |
363 | | /** |
364 | | * Updates accessible tree when rendered text is changed. |
365 | | */ |
366 | | void UpdateText(nsIContent* aTextNode); |
367 | | |
368 | | /** |
369 | | * Recreate an accessible, results in hide/show events pair. |
370 | | */ |
371 | | void RecreateAccessible(nsIContent* aContent); |
372 | | |
373 | | /** |
374 | | * Schedule ARIA owned element relocation if needed. Return true if relocation |
375 | | * was scheduled. |
376 | | */ |
377 | | bool RelocateARIAOwnedIfNeeded(nsIContent* aEl); |
378 | | |
379 | | /** |
380 | | * Return a notification controller associated with the document. |
381 | | */ |
382 | | NotificationController* Controller() const { return mNotificationController; } |
383 | | |
384 | | /** |
385 | | * If this document is in a content process return the object responsible for |
386 | | * communicating with the main process for it. |
387 | | */ |
388 | | DocAccessibleChild* IPCDoc() const { return mIPCDoc; } |
389 | | |
390 | | protected: |
391 | | virtual ~DocAccessible(); |
392 | | |
393 | | void LastRelease(); |
394 | | |
395 | | // DocAccessible |
396 | | virtual nsresult AddEventListeners(); |
397 | | virtual nsresult RemoveEventListeners(); |
398 | | |
399 | | /** |
400 | | * Marks this document as loaded or loading. |
401 | | */ |
402 | | void NotifyOfLoad(uint32_t aLoadEventType); |
403 | | void NotifyOfLoading(bool aIsReloading); |
404 | | |
405 | | friend class DocManager; |
406 | | |
407 | | /** |
408 | | * Perform initial update (create accessible tree). |
409 | | * Can be overridden by wrappers to prepare initialization work. |
410 | | */ |
411 | | virtual void DoInitialUpdate(); |
412 | | |
413 | | /** |
414 | | * Updates root element and picks up ARIA role on it if any. |
415 | | */ |
416 | | void UpdateRootElIfNeeded(); |
417 | | |
418 | | /** |
419 | | * Process document load notification, fire document load and state busy |
420 | | * events if applicable. |
421 | | */ |
422 | | void ProcessLoad(); |
423 | | |
424 | | /** |
425 | | * Add/remove scroll listeners, @see nsIScrollPositionListener interface. |
426 | | */ |
427 | | void AddScrollListener(); |
428 | | void RemoveScrollListener(); |
429 | | |
430 | | /** |
431 | | * Append the given document accessible to this document's child document |
432 | | * accessibles. |
433 | | */ |
434 | | bool AppendChildDocument(DocAccessible* aChildDocument) |
435 | | { |
436 | | return mChildDocuments.AppendElement(aChildDocument); |
437 | | } |
438 | | |
439 | | /** |
440 | | * Remove the given document accessible from this document's child document |
441 | | * accessibles. |
442 | | */ |
443 | | void RemoveChildDocument(DocAccessible* aChildDocument) |
444 | | { |
445 | | mChildDocuments.RemoveElement(aChildDocument); |
446 | | } |
447 | | |
448 | | /** |
449 | | * Add dependent IDs pointed by accessible element by relation attribute to |
450 | | * cache. If the relation attribute is missed then all relation attributes |
451 | | * are checked. |
452 | | * |
453 | | * @param aRelProvider [in] accessible that element has relation attribute |
454 | | * @param aRelAttr [in, optional] relation attribute |
455 | | */ |
456 | | void AddDependentIDsFor(Accessible* aRelProvider, |
457 | | nsAtom* aRelAttr = nullptr); |
458 | | |
459 | | /** |
460 | | * Remove dependent IDs pointed by accessible element by relation attribute |
461 | | * from cache. If the relation attribute is absent then all relation |
462 | | * attributes are checked. |
463 | | * |
464 | | * @param aRelProvider [in] accessible that element has relation attribute |
465 | | * @param aRelAttr [in, optional] relation attribute |
466 | | */ |
467 | | void RemoveDependentIDsFor(Accessible* aRelProvider, |
468 | | nsAtom* aRelAttr = nullptr); |
469 | | |
470 | | /** |
471 | | * Update or recreate an accessible depending on a changed attribute. |
472 | | * |
473 | | * @param aElement [in] the element the attribute was changed on |
474 | | * @param aAttribute [in] the changed attribute |
475 | | * @return true if an action was taken on the attribute change |
476 | | */ |
477 | | bool UpdateAccessibleOnAttrChange(mozilla::dom::Element* aElement, |
478 | | nsAtom* aAttribute); |
479 | | |
480 | | /** |
481 | | * Fire accessible events when attribute is changed. |
482 | | * |
483 | | * @param aAccessible [in] accessible the DOM attribute is changed for |
484 | | * @param aNameSpaceID [in] namespace of changed attribute |
485 | | * @param aAttribute [in] changed attribute |
486 | | */ |
487 | | void AttributeChangedImpl(Accessible* aAccessible, |
488 | | int32_t aNameSpaceID, nsAtom* aAttribute); |
489 | | |
490 | | /** |
491 | | * Fire accessible events when ARIA attribute is changed. |
492 | | * |
493 | | * @param aAccessible [in] accesislbe the DOM attribute is changed for |
494 | | * @param aAttribute [in] changed attribute |
495 | | */ |
496 | | void ARIAAttributeChanged(Accessible* aAccessible, nsAtom* aAttribute); |
497 | | |
498 | | /** |
499 | | * Process ARIA active-descendant attribute change. |
500 | | */ |
501 | | void ARIAActiveDescendantChanged(Accessible* aAccessible); |
502 | | |
503 | | /** |
504 | | * Update the accessible tree for inserted content. |
505 | | */ |
506 | | void ProcessContentInserted(Accessible* aContainer, |
507 | | const nsTArray<nsCOMPtr<nsIContent> >* aInsertedContent); |
508 | | void ProcessContentInserted(Accessible* aContainer, |
509 | | nsIContent* aInsertedContent); |
510 | | |
511 | | /** |
512 | | * Used to notify the document to make it process the invalidation list. |
513 | | * |
514 | | * While children are cached we may encounter the case there's no accessible |
515 | | * for referred content by related accessible. Store these related nodes to |
516 | | * invalidate their containers later. |
517 | | */ |
518 | | void ProcessInvalidationList(); |
519 | | |
520 | | /** |
521 | | * Steals or puts back accessible subtrees. |
522 | | */ |
523 | | void DoARIAOwnsRelocation(Accessible* aOwner); |
524 | | |
525 | | /** |
526 | | * Moves children back under their original parents. |
527 | | */ |
528 | | void PutChildrenBack(nsTArray<RefPtr<Accessible> >* aChildren, |
529 | | uint32_t aStartIdx); |
530 | | |
531 | | bool MoveChild(Accessible* aChild, Accessible* aNewParent, |
532 | | int32_t aIdxInParent); |
533 | | |
534 | | /** |
535 | | * Create accessible tree. |
536 | | * |
537 | | * @param aRoot [in] a root of subtree to create |
538 | | * @param aFocusedAcc [in, optional] a focused accessible under created |
539 | | * subtree if any |
540 | | */ |
541 | | void CacheChildrenInSubtree(Accessible* aRoot, |
542 | | Accessible** aFocusedAcc = nullptr); |
543 | | void CreateSubtree(Accessible* aRoot); |
544 | | |
545 | | /** |
546 | | * Remove accessibles in subtree from node to accessible map. |
547 | | */ |
548 | | void UncacheChildrenInSubtree(Accessible* aRoot); |
549 | | |
550 | | /** |
551 | | * Shutdown any cached accessible in the subtree. |
552 | | * |
553 | | * @param aAccessible [in] the root of the subrtee to invalidate accessible |
554 | | * child/parent refs in |
555 | | */ |
556 | | void ShutdownChildrenInSubtree(Accessible* aAccessible); |
557 | | |
558 | | /** |
559 | | * Return true if the document is a target of document loading events |
560 | | * (for example, state busy change or document reload events). |
561 | | * |
562 | | * Rules: The root chrome document accessible is never an event target |
563 | | * (for example, Firefox UI window). If the sub document is loaded within its |
564 | | * parent document then the parent document is a target only (aka events |
565 | | * coalescence). |
566 | | */ |
567 | | bool IsLoadEventTarget() const; |
568 | | |
569 | | /* |
570 | | * Set the object responsible for communicating with the main process on |
571 | | * behalf of this document. |
572 | | */ |
573 | | void SetIPCDoc(DocAccessibleChild* aIPCDoc) { mIPCDoc = aIPCDoc; } |
574 | | |
575 | | friend class DocAccessibleChildBase; |
576 | | |
577 | | /** |
578 | | * Used to fire scrolling end event after page scroll. |
579 | | * |
580 | | * @param aTimer [in] the timer object |
581 | | * @param aClosure [in] the document accessible where scrolling happens |
582 | | */ |
583 | | static void ScrollTimerCallback(nsITimer* aTimer, void* aClosure); |
584 | | |
585 | | void DispatchScrollingEvent(uint32_t aEventType); |
586 | | |
587 | | /** |
588 | | * Check if an id attribute change affects aria-activedescendant and handle |
589 | | * the aria-activedescendant change if appropriate. |
590 | | * If the currently focused element has aria-activedescendant and an |
591 | | * element's id changes to match this, the id was probably moved from the |
592 | | * previous active descendant, thus making this element the new active |
593 | | * descendant. In that case, accessible focus must be changed accordingly. |
594 | | */ |
595 | | void ARIAActiveDescendantIDMaybeMoved(dom::Element* aElm); |
596 | | |
597 | | protected: |
598 | | |
599 | | /** |
600 | | * State and property flags, kept by mDocFlags. |
601 | | */ |
602 | | enum { |
603 | | // Whether scroll listeners were added. |
604 | | eScrollInitialized = 1 << 0, |
605 | | |
606 | | // Whether the document is a tab document. |
607 | | eTabDocument = 1 << 1 |
608 | | }; |
609 | | |
610 | | /** |
611 | | * Cache of accessibles within this document accessible. |
612 | | */ |
613 | | AccessibleHashtable mAccessibleCache; |
614 | | nsDataHashtable<nsPtrHashKey<const nsINode>, Accessible*> |
615 | | mNodeToAccessibleMap; |
616 | | |
617 | | nsIDocument* mDocumentNode; |
618 | | nsCOMPtr<nsITimer> mScrollWatchTimer; |
619 | | uint16_t mScrollPositionChangedTicks; // Used for tracking scroll events |
620 | | TimeStamp mLastScrollingDispatch; |
621 | | |
622 | | /** |
623 | | * Bit mask of document load states (@see LoadState). |
624 | | */ |
625 | | uint32_t mLoadState : 3; |
626 | | |
627 | | /** |
628 | | * Bit mask of other states and props. |
629 | | */ |
630 | | uint32_t mDocFlags : 28; |
631 | | |
632 | | /** |
633 | | * Type of document load event fired after the document is loaded completely. |
634 | | */ |
635 | | uint32_t mLoadEventType; |
636 | | |
637 | | /** |
638 | | * Reference to anchor jump element. |
639 | | */ |
640 | | nsCOMPtr<nsIContent> mAnchorJumpElm; |
641 | | |
642 | | /** |
643 | | * A generic state (see items below) before the attribute value was changed. |
644 | | * @see AttributeWillChange and AttributeChanged notifications. |
645 | | */ |
646 | | union { |
647 | | // ARIA attribute value |
648 | | nsAtom* mARIAAttrOldValue; |
649 | | |
650 | | // True if the accessible state bit was on |
651 | | bool mStateBitWasOn; |
652 | | }; |
653 | | |
654 | | nsTArray<RefPtr<DocAccessible> > mChildDocuments; |
655 | | |
656 | | /** |
657 | | * The virtual cursor of the document. |
658 | | */ |
659 | | RefPtr<nsAccessiblePivot> mVirtualCursor; |
660 | | |
661 | | /** |
662 | | * A storage class for pairing content with one of its relation attributes. |
663 | | */ |
664 | | class AttrRelProvider |
665 | | { |
666 | | public: |
667 | | AttrRelProvider(nsAtom* aRelAttr, nsIContent* aContent) : |
668 | | mRelAttr(aRelAttr), mContent(aContent) { } |
669 | | |
670 | | nsAtom* mRelAttr; |
671 | | nsCOMPtr<nsIContent> mContent; |
672 | | |
673 | | private: |
674 | | AttrRelProvider(); |
675 | | AttrRelProvider(const AttrRelProvider&); |
676 | | AttrRelProvider& operator =(const AttrRelProvider&); |
677 | | }; |
678 | | |
679 | | /** |
680 | | * The cache of IDs pointed by relation attributes. |
681 | | */ |
682 | | typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray; |
683 | | nsClassHashtable<nsStringHashKey, AttrRelProviderArray> |
684 | | mDependentIDsHash; |
685 | | |
686 | | friend class RelatedAccIterator; |
687 | | |
688 | | /** |
689 | | * Used for our caching algorithm. We store the list of nodes that should be |
690 | | * invalidated. |
691 | | * |
692 | | * @see ProcessInvalidationList |
693 | | */ |
694 | | nsTArray<RefPtr<nsIContent>> mInvalidationList; |
695 | | |
696 | | /** |
697 | | * Holds a list of aria-owns relocations. |
698 | | */ |
699 | | nsClassHashtable<nsPtrHashKey<Accessible>, nsTArray<RefPtr<Accessible> > > |
700 | | mARIAOwnsHash; |
701 | | |
702 | | /** |
703 | | * Used to process notification from core and accessible events. |
704 | | */ |
705 | | RefPtr<NotificationController> mNotificationController; |
706 | | friend class EventTree; |
707 | | friend class NotificationController; |
708 | | |
709 | | private: |
710 | | |
711 | | nsIPresShell* mPresShell; |
712 | | |
713 | | // Exclusively owned by IPDL so don't manually delete it! |
714 | | DocAccessibleChild* mIPCDoc; |
715 | | }; |
716 | | |
717 | | inline DocAccessible* |
718 | | Accessible::AsDoc() |
719 | 0 | { |
720 | 0 | return IsDoc() ? static_cast<DocAccessible*>(this) : nullptr; |
721 | 0 | } |
722 | | |
723 | | } // namespace a11y |
724 | | } // namespace mozilla |
725 | | |
726 | | #endif |