1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/generic/DocAccessible.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,625 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef mozilla_a11y_DocAccessible_h__ 1.10 +#define mozilla_a11y_DocAccessible_h__ 1.11 + 1.12 +#include "nsIAccessibleDocument.h" 1.13 +#include "nsIAccessiblePivot.h" 1.14 + 1.15 +#include "AccEvent.h" 1.16 +#include "HyperTextAccessibleWrap.h" 1.17 + 1.18 +#include "nsClassHashtable.h" 1.19 +#include "nsDataHashtable.h" 1.20 +#include "nsIDocument.h" 1.21 +#include "nsIDocumentObserver.h" 1.22 +#include "nsIEditor.h" 1.23 +#include "nsIObserver.h" 1.24 +#include "nsIScrollPositionListener.h" 1.25 +#include "nsITimer.h" 1.26 +#include "nsIWeakReference.h" 1.27 + 1.28 +class nsAccessiblePivot; 1.29 + 1.30 +class nsIScrollableView; 1.31 + 1.32 +const uint32_t kDefaultCacheSize = 256; 1.33 + 1.34 +namespace mozilla { 1.35 +namespace a11y { 1.36 + 1.37 +class DocManager; 1.38 +class NotificationController; 1.39 +class RelatedAccIterator; 1.40 +template<class Class, class Arg> 1.41 +class TNotification; 1.42 + 1.43 +class DocAccessible : public HyperTextAccessibleWrap, 1.44 + public nsIAccessibleDocument, 1.45 + public nsIDocumentObserver, 1.46 + public nsIObserver, 1.47 + public nsIScrollPositionListener, 1.48 + public nsSupportsWeakReference, 1.49 + public nsIAccessiblePivotObserver 1.50 +{ 1.51 + NS_DECL_ISUPPORTS_INHERITED 1.52 + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DocAccessible, Accessible) 1.53 + 1.54 + NS_DECL_NSIACCESSIBLEDOCUMENT 1.55 + 1.56 + NS_DECL_NSIOBSERVER 1.57 + 1.58 + NS_DECL_NSIACCESSIBLEPIVOTOBSERVER 1.59 + 1.60 +public: 1.61 + 1.62 + DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent, 1.63 + nsIPresShell* aPresShell); 1.64 + virtual ~DocAccessible(); 1.65 + 1.66 + // nsIAccessible 1.67 + NS_IMETHOD TakeFocus(void); 1.68 + 1.69 + // nsIScrollPositionListener 1.70 + virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) {} 1.71 + virtual void ScrollPositionDidChange(nscoord aX, nscoord aY); 1.72 + 1.73 + // nsIDocumentObserver 1.74 + NS_DECL_NSIDOCUMENTOBSERVER 1.75 + 1.76 + // Accessible 1.77 + virtual void Init(); 1.78 + virtual void Shutdown(); 1.79 + virtual nsIFrame* GetFrame() const; 1.80 + virtual nsINode* GetNode() const { return mDocumentNode; } 1.81 + nsIDocument* DocumentNode() const { return mDocumentNode; } 1.82 + 1.83 + virtual mozilla::a11y::ENameValueFlag Name(nsString& aName); 1.84 + virtual void Description(nsString& aDescription); 1.85 + virtual Accessible* FocusedChild(); 1.86 + virtual mozilla::a11y::role NativeRole(); 1.87 + virtual uint64_t NativeState(); 1.88 + virtual uint64_t NativeInteractiveState() const; 1.89 + virtual bool NativelyUnavailable() const; 1.90 + virtual void ApplyARIAState(uint64_t* aState) const; 1.91 + virtual already_AddRefed<nsIPersistentProperties> Attributes(); 1.92 + 1.93 +#ifdef A11Y_LOG 1.94 + virtual nsresult HandleAccEvent(AccEvent* aEvent); 1.95 +#endif 1.96 + 1.97 + virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); 1.98 + 1.99 + // HyperTextAccessible 1.100 + virtual already_AddRefed<nsIEditor> GetEditor() const; 1.101 + 1.102 + // DocAccessible 1.103 + 1.104 + /** 1.105 + * Return presentation shell for this document accessible. 1.106 + */ 1.107 + nsIPresShell* PresShell() const { return mPresShell; } 1.108 + 1.109 + /** 1.110 + * Return the presentation shell's context. 1.111 + */ 1.112 + nsPresContext* PresContext() const { return mPresShell->GetPresContext(); } 1.113 + 1.114 + /** 1.115 + * Return true if associated DOM document was loaded and isn't unloading. 1.116 + */ 1.117 + bool IsContentLoaded() const 1.118 + { 1.119 + // eDOMLoaded flag check is used for error pages as workaround to make this 1.120 + // method return correct result since error pages do not receive 'pageshow' 1.121 + // event and as consequence nsIDocument::IsShowing() returns false. 1.122 + return mDocumentNode && mDocumentNode->IsVisible() && 1.123 + (mDocumentNode->IsShowing() || HasLoadState(eDOMLoaded)); 1.124 + } 1.125 + 1.126 + /** 1.127 + * Document load states. 1.128 + */ 1.129 + enum LoadState { 1.130 + // initial tree construction is pending 1.131 + eTreeConstructionPending = 0, 1.132 + // initial tree construction done 1.133 + eTreeConstructed = 1, 1.134 + // DOM document is loaded. 1.135 + eDOMLoaded = 1 << 1, 1.136 + // document is ready 1.137 + eReady = eTreeConstructed | eDOMLoaded, 1.138 + // document and all its subdocuments are ready 1.139 + eCompletelyLoaded = eReady | 1 << 2 1.140 + }; 1.141 + 1.142 + /** 1.143 + * Return true if the document has given document state. 1.144 + */ 1.145 + bool HasLoadState(LoadState aState) const 1.146 + { return (mLoadState & static_cast<uint32_t>(aState)) == 1.147 + static_cast<uint32_t>(aState); } 1.148 + 1.149 + /** 1.150 + * Return a native window handler or pointer depending on platform. 1.151 + */ 1.152 + virtual void* GetNativeWindow() const; 1.153 + 1.154 + /** 1.155 + * Return the parent document. 1.156 + */ 1.157 + DocAccessible* ParentDocument() const 1.158 + { return mParent ? mParent->Document() : nullptr; } 1.159 + 1.160 + /** 1.161 + * Return the child document count. 1.162 + */ 1.163 + uint32_t ChildDocumentCount() const 1.164 + { return mChildDocuments.Length(); } 1.165 + 1.166 + /** 1.167 + * Return the child document at the given index. 1.168 + */ 1.169 + DocAccessible* GetChildDocumentAt(uint32_t aIndex) const 1.170 + { return mChildDocuments.SafeElementAt(aIndex, nullptr); } 1.171 + 1.172 + /** 1.173 + * Fire accessible event asynchronously. 1.174 + */ 1.175 + void FireDelayedEvent(AccEvent* aEvent); 1.176 + void FireDelayedEvent(uint32_t aEventType, Accessible* aTarget); 1.177 + 1.178 + /** 1.179 + * Fire value change event on the given accessible if applicable. 1.180 + */ 1.181 + void MaybeNotifyOfValueChange(Accessible* aAccessible); 1.182 + 1.183 + /** 1.184 + * Get/set the anchor jump. 1.185 + */ 1.186 + Accessible* AnchorJump() 1.187 + { return GetAccessibleOrContainer(mAnchorJumpElm); } 1.188 + 1.189 + void SetAnchorJump(nsIContent* aTargetNode) 1.190 + { mAnchorJumpElm = aTargetNode; } 1.191 + 1.192 + /** 1.193 + * Bind the child document to the tree. 1.194 + */ 1.195 + void BindChildDocument(DocAccessible* aDocument); 1.196 + 1.197 + /** 1.198 + * Process the generic notification. 1.199 + * 1.200 + * @note The caller must guarantee that the given instance still exists when 1.201 + * notification is processed. 1.202 + * @see NotificationController::HandleNotification 1.203 + */ 1.204 + template<class Class, class Arg> 1.205 + void HandleNotification(Class* aInstance, 1.206 + typename TNotification<Class, Arg>::Callback aMethod, 1.207 + Arg* aArg); 1.208 + 1.209 + /** 1.210 + * Return the cached accessible by the given DOM node if it's in subtree of 1.211 + * this document accessible or the document accessible itself, otherwise null. 1.212 + * 1.213 + * @return the accessible object 1.214 + */ 1.215 + Accessible* GetAccessible(nsINode* aNode) const; 1.216 + 1.217 + /** 1.218 + * Return an accessible for the given node even if the node is not in 1.219 + * document's node map cache (like HTML area element). 1.220 + * 1.221 + * XXX: it should be really merged with GetAccessible(). 1.222 + */ 1.223 + Accessible* GetAccessibleEvenIfNotInMap(nsINode* aNode) const; 1.224 + Accessible* GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const; 1.225 + 1.226 + /** 1.227 + * Return whether the given DOM node has an accessible or not. 1.228 + */ 1.229 + bool HasAccessible(nsINode* aNode) const 1.230 + { return GetAccessible(aNode); } 1.231 + 1.232 + /** 1.233 + * Return the cached accessible by the given unique ID within this document. 1.234 + * 1.235 + * @note the unique ID matches with the uniqueID() of Accessible 1.236 + * 1.237 + * @param aUniqueID [in] the unique ID used to cache the node. 1.238 + */ 1.239 + Accessible* GetAccessibleByUniqueID(void* aUniqueID) 1.240 + { 1.241 + return UniqueID() == aUniqueID ? 1.242 + this : mAccessibleCache.GetWeak(aUniqueID); 1.243 + } 1.244 + 1.245 + /** 1.246 + * Return the cached accessible by the given unique ID looking through 1.247 + * this and nested documents. 1.248 + */ 1.249 + Accessible* GetAccessibleByUniqueIDInSubtree(void* aUniqueID); 1.250 + 1.251 + /** 1.252 + * Return an accessible for the given DOM node or container accessible if 1.253 + * the node is not accessible. 1.254 + */ 1.255 + Accessible* GetAccessibleOrContainer(nsINode* aNode) const; 1.256 + 1.257 + /** 1.258 + * Return a container accessible for the given DOM node. 1.259 + */ 1.260 + Accessible* GetContainerAccessible(nsINode* aNode) const 1.261 + { 1.262 + return aNode ? GetAccessibleOrContainer(aNode->GetParentNode()) : nullptr; 1.263 + } 1.264 + 1.265 + /** 1.266 + * Return an accessible for the given node or its first accessible descendant. 1.267 + */ 1.268 + Accessible* GetAccessibleOrDescendant(nsINode* aNode) const; 1.269 + 1.270 + /** 1.271 + * Return true if the given ID is referred by relation attribute. 1.272 + * 1.273 + * @note Different elements may share the same ID if they are hosted inside 1.274 + * XBL bindings. Be careful the result of this method may be senseless 1.275 + * while it's called for XUL elements (where XBL is used widely). 1.276 + */ 1.277 + bool IsDependentID(const nsAString& aID) const 1.278 + { return mDependentIDsHash.Get(aID, nullptr); } 1.279 + 1.280 + /** 1.281 + * Initialize the newly created accessible and put it into document caches. 1.282 + * 1.283 + * @param aAccessible [in] created accessible 1.284 + * @param aRoleMapEntry [in] the role map entry role the ARIA role or nullptr 1.285 + * if none 1.286 + */ 1.287 + void BindToDocument(Accessible* aAccessible, nsRoleMapEntry* aRoleMapEntry); 1.288 + 1.289 + /** 1.290 + * Remove from document and shutdown the given accessible. 1.291 + */ 1.292 + void UnbindFromDocument(Accessible* aAccessible); 1.293 + 1.294 + /** 1.295 + * Notify the document accessible that content was inserted. 1.296 + */ 1.297 + void ContentInserted(nsIContent* aContainerNode, 1.298 + nsIContent* aStartChildNode, 1.299 + nsIContent* aEndChildNode); 1.300 + 1.301 + /** 1.302 + * Notify the document accessible that content was removed. 1.303 + */ 1.304 + void ContentRemoved(nsIContent* aContainerNode, nsIContent* aChildNode); 1.305 + 1.306 + /** 1.307 + * Updates accessible tree when rendered text is changed. 1.308 + */ 1.309 + void UpdateText(nsIContent* aTextNode); 1.310 + 1.311 + /** 1.312 + * Recreate an accessible, results in hide/show events pair. 1.313 + */ 1.314 + void RecreateAccessible(nsIContent* aContent); 1.315 + 1.316 +protected: 1.317 + 1.318 + void LastRelease(); 1.319 + 1.320 + // Accessible 1.321 + virtual void CacheChildren(); 1.322 + 1.323 + // DocAccessible 1.324 + virtual nsresult AddEventListeners(); 1.325 + virtual nsresult RemoveEventListeners(); 1.326 + 1.327 + /** 1.328 + * Marks this document as loaded or loading. 1.329 + */ 1.330 + void NotifyOfLoad(uint32_t aLoadEventType); 1.331 + void NotifyOfLoading(bool aIsReloading); 1.332 + 1.333 + friend class DocManager; 1.334 + 1.335 + /** 1.336 + * Perform initial update (create accessible tree). 1.337 + * Can be overridden by wrappers to prepare initialization work. 1.338 + */ 1.339 + virtual void DoInitialUpdate(); 1.340 + 1.341 + /** 1.342 + * Process document load notification, fire document load and state busy 1.343 + * events if applicable. 1.344 + */ 1.345 + void ProcessLoad(); 1.346 + 1.347 + /** 1.348 + * Add/remove scroll listeners, @see nsIScrollPositionListener interface. 1.349 + */ 1.350 + void AddScrollListener(); 1.351 + void RemoveScrollListener(); 1.352 + 1.353 + /** 1.354 + * Append the given document accessible to this document's child document 1.355 + * accessibles. 1.356 + */ 1.357 + bool AppendChildDocument(DocAccessible* aChildDocument) 1.358 + { 1.359 + return mChildDocuments.AppendElement(aChildDocument); 1.360 + } 1.361 + 1.362 + /** 1.363 + * Remove the given document accessible from this document's child document 1.364 + * accessibles. 1.365 + */ 1.366 + void RemoveChildDocument(DocAccessible* aChildDocument) 1.367 + { 1.368 + mChildDocuments.RemoveElement(aChildDocument); 1.369 + } 1.370 + 1.371 + /** 1.372 + * Add dependent IDs pointed by accessible element by relation attribute to 1.373 + * cache. If the relation attribute is missed then all relation attributes 1.374 + * are checked. 1.375 + * 1.376 + * @param aRelProvider [in] accessible that element has relation attribute 1.377 + * @param aRelAttr [in, optional] relation attribute 1.378 + */ 1.379 + void AddDependentIDsFor(dom::Element* aRelProviderElm, 1.380 + nsIAtom* aRelAttr = nullptr); 1.381 + 1.382 + /** 1.383 + * Remove dependent IDs pointed by accessible element by relation attribute 1.384 + * from cache. If the relation attribute is absent then all relation 1.385 + * attributes are checked. 1.386 + * 1.387 + * @param aRelProvider [in] accessible that element has relation attribute 1.388 + * @param aRelAttr [in, optional] relation attribute 1.389 + */ 1.390 + void RemoveDependentIDsFor(dom::Element* aRelProviderElm, 1.391 + nsIAtom* aRelAttr = nullptr); 1.392 + 1.393 + /** 1.394 + * Update or recreate an accessible depending on a changed attribute. 1.395 + * 1.396 + * @param aElement [in] the element the attribute was changed on 1.397 + * @param aAttribute [in] the changed attribute 1.398 + * @return true if an action was taken on the attribute change 1.399 + */ 1.400 + bool UpdateAccessibleOnAttrChange(mozilla::dom::Element* aElement, 1.401 + nsIAtom* aAttribute); 1.402 + 1.403 + /** 1.404 + * Fire accessible events when attribute is changed. 1.405 + * 1.406 + * @param aAccessible [in] accessible the DOM attribute is changed for 1.407 + * @param aNameSpaceID [in] namespace of changed attribute 1.408 + * @param aAttribute [in] changed attribute 1.409 + */ 1.410 + void AttributeChangedImpl(Accessible* aAccessible, 1.411 + int32_t aNameSpaceID, nsIAtom* aAttribute); 1.412 + 1.413 + /** 1.414 + * Fire accessible events when ARIA attribute is changed. 1.415 + * 1.416 + * @param aAccessible [in] accesislbe the DOM attribute is changed for 1.417 + * @param aAttribute [in] changed attribute 1.418 + */ 1.419 + void ARIAAttributeChanged(Accessible* aAccessible, nsIAtom* aAttribute); 1.420 + 1.421 + /** 1.422 + * Process ARIA active-descendant attribute change. 1.423 + */ 1.424 + void ARIAActiveDescendantChanged(Accessible* aAccessible); 1.425 + 1.426 + /** 1.427 + * Update the accessible tree for inserted content. 1.428 + */ 1.429 + void ProcessContentInserted(Accessible* aContainer, 1.430 + const nsTArray<nsCOMPtr<nsIContent> >* aInsertedContent); 1.431 + 1.432 + /** 1.433 + * Used to notify the document to make it process the invalidation list. 1.434 + * 1.435 + * While children are cached we may encounter the case there's no accessible 1.436 + * for referred content by related accessible. Store these related nodes to 1.437 + * invalidate their containers later. 1.438 + */ 1.439 + void ProcessInvalidationList(); 1.440 + 1.441 + /** 1.442 + * Update the accessible tree for content insertion or removal. 1.443 + */ 1.444 + void UpdateTree(Accessible* aContainer, nsIContent* aChildNode, 1.445 + bool aIsInsert); 1.446 + 1.447 + /** 1.448 + * Helper for UpdateTree() method. Go down to DOM subtree and updates 1.449 + * accessible tree. Return one of these flags. 1.450 + */ 1.451 + enum EUpdateTreeFlags { 1.452 + eNoAccessible = 0, 1.453 + eAccessible = 1, 1.454 + eAlertAccessible = 2 1.455 + }; 1.456 + 1.457 + uint32_t UpdateTreeInternal(Accessible* aChild, bool aIsInsert, 1.458 + AccReorderEvent* aReorderEvent); 1.459 + 1.460 + /** 1.461 + * Create accessible tree. 1.462 + * 1.463 + * @param aRoot [in] a root of subtree to create 1.464 + * @param aFocusedAcc [in, optional] a focused accessible under created 1.465 + * subtree if any 1.466 + */ 1.467 + void CacheChildrenInSubtree(Accessible* aRoot, 1.468 + Accessible** aFocusedAcc = nullptr); 1.469 + 1.470 + /** 1.471 + * Remove accessibles in subtree from node to accessible map. 1.472 + */ 1.473 + void UncacheChildrenInSubtree(Accessible* aRoot); 1.474 + 1.475 + /** 1.476 + * Shutdown any cached accessible in the subtree. 1.477 + * 1.478 + * @param aAccessible [in] the root of the subrtee to invalidate accessible 1.479 + * child/parent refs in 1.480 + */ 1.481 + void ShutdownChildrenInSubtree(Accessible* aAccessible); 1.482 + 1.483 + /** 1.484 + * Return true if the document is a target of document loading events 1.485 + * (for example, state busy change or document reload events). 1.486 + * 1.487 + * Rules: The root chrome document accessible is never an event target 1.488 + * (for example, Firefox UI window). If the sub document is loaded within its 1.489 + * parent document then the parent document is a target only (aka events 1.490 + * coalescence). 1.491 + */ 1.492 + bool IsLoadEventTarget() const; 1.493 + 1.494 + /** 1.495 + * Used to fire scrolling end event after page scroll. 1.496 + * 1.497 + * @param aTimer [in] the timer object 1.498 + * @param aClosure [in] the document accessible where scrolling happens 1.499 + */ 1.500 + static void ScrollTimerCallback(nsITimer* aTimer, void* aClosure); 1.501 + 1.502 +protected: 1.503 + 1.504 + /** 1.505 + * State and property flags, kept by mDocFlags. 1.506 + */ 1.507 + enum { 1.508 + // Whether scroll listeners were added. 1.509 + eScrollInitialized = 1 << 0, 1.510 + 1.511 + // Whether the document is a tab document. 1.512 + eTabDocument = 1 << 1 1.513 + }; 1.514 + 1.515 + /** 1.516 + * Cache of accessibles within this document accessible. 1.517 + */ 1.518 + AccessibleHashtable mAccessibleCache; 1.519 + nsDataHashtable<nsPtrHashKey<const nsINode>, Accessible*> 1.520 + mNodeToAccessibleMap; 1.521 + 1.522 + nsIDocument* mDocumentNode; 1.523 + nsCOMPtr<nsITimer> mScrollWatchTimer; 1.524 + uint16_t mScrollPositionChangedTicks; // Used for tracking scroll events 1.525 + 1.526 + /** 1.527 + * Bit mask of document load states (@see LoadState). 1.528 + */ 1.529 + uint32_t mLoadState : 3; 1.530 + 1.531 + /** 1.532 + * Bit mask of other states and props. 1.533 + */ 1.534 + uint32_t mDocFlags : 28; 1.535 + 1.536 + /** 1.537 + * Type of document load event fired after the document is loaded completely. 1.538 + */ 1.539 + uint32_t mLoadEventType; 1.540 + 1.541 + /** 1.542 + * Reference to anchor jump element. 1.543 + */ 1.544 + nsCOMPtr<nsIContent> mAnchorJumpElm; 1.545 + 1.546 + /** 1.547 + * A generic state (see items below) before the attribute value was changed. 1.548 + * @see AttributeWillChange and AttributeChanged notifications. 1.549 + */ 1.550 + union { 1.551 + // ARIA attribute value 1.552 + nsIAtom* mARIAAttrOldValue; 1.553 + 1.554 + // True if the accessible state bit was on 1.555 + bool mStateBitWasOn; 1.556 + }; 1.557 + 1.558 + nsTArray<nsRefPtr<DocAccessible> > mChildDocuments; 1.559 + 1.560 + /** 1.561 + * The virtual cursor of the document. 1.562 + */ 1.563 + nsRefPtr<nsAccessiblePivot> mVirtualCursor; 1.564 + 1.565 + /** 1.566 + * A storage class for pairing content with one of its relation attributes. 1.567 + */ 1.568 + class AttrRelProvider 1.569 + { 1.570 + public: 1.571 + AttrRelProvider(nsIAtom* aRelAttr, nsIContent* aContent) : 1.572 + mRelAttr(aRelAttr), mContent(aContent) { } 1.573 + 1.574 + nsIAtom* mRelAttr; 1.575 + nsCOMPtr<nsIContent> mContent; 1.576 + 1.577 + private: 1.578 + AttrRelProvider(); 1.579 + AttrRelProvider(const AttrRelProvider&); 1.580 + AttrRelProvider& operator =(const AttrRelProvider&); 1.581 + }; 1.582 + 1.583 + typedef nsTArray<nsAutoPtr<AttrRelProvider> > AttrRelProviderArray; 1.584 + typedef nsClassHashtable<nsStringHashKey, AttrRelProviderArray> 1.585 + DependentIDsHashtable; 1.586 + 1.587 + /** 1.588 + * The cache of IDs pointed by relation attributes. 1.589 + */ 1.590 + DependentIDsHashtable mDependentIDsHash; 1.591 + 1.592 + static PLDHashOperator 1.593 + CycleCollectorTraverseDepIDsEntry(const nsAString& aKey, 1.594 + AttrRelProviderArray* aProviders, 1.595 + void* aUserArg); 1.596 + 1.597 + friend class RelatedAccIterator; 1.598 + 1.599 + /** 1.600 + * Used for our caching algorithm. We store the list of nodes that should be 1.601 + * invalidated. 1.602 + * 1.603 + * @see ProcessInvalidationList 1.604 + */ 1.605 + nsTArray<nsIContent*> mInvalidationList; 1.606 + 1.607 + /** 1.608 + * Used to process notification from core and accessible events. 1.609 + */ 1.610 + nsRefPtr<NotificationController> mNotificationController; 1.611 + friend class EventQueue; 1.612 + friend class NotificationController; 1.613 + 1.614 +private: 1.615 + 1.616 + nsIPresShell* mPresShell; 1.617 +}; 1.618 + 1.619 +inline DocAccessible* 1.620 +Accessible::AsDoc() 1.621 +{ 1.622 + return IsDoc() ? static_cast<DocAccessible*>(this) : nullptr; 1.623 +} 1.624 + 1.625 +} // namespace a11y 1.626 +} // namespace mozilla 1.627 + 1.628 +#endif