DocAccessible-inl.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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 file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_a11y_DocAccessible_inl_h_
  6. #define mozilla_a11y_DocAccessible_inl_h_
  7. #include "DocAccessible.h"
  8. #include "nsAccessibilityService.h"
  9. #include "nsAccessiblePivot.h"
  10. #include "NotificationController.h"
  11. #include "States.h"
  12. #include "nsIScrollableFrame.h"
  13. #include "nsIDocumentInlines.h"
  14. #ifdef A11Y_LOG
  15. #include "Logging.h"
  16. #endif
  17. namespace mozilla {
  18. namespace a11y {
  19. inline Accessible*
  20. DocAccessible::AccessibleOrTrueContainer(nsINode* aNode) const
  21. {
  22. // HTML comboboxes have no-content list accessible as an intermediate
  23. // containing all options.
  24. Accessible* container = GetAccessibleOrContainer(aNode);
  25. if (container && container->IsHTMLCombobox()) {
  26. return container->FirstChild();
  27. }
  28. return container;
  29. }
  30. inline nsIAccessiblePivot*
  31. DocAccessible::VirtualCursor()
  32. {
  33. if (!mVirtualCursor) {
  34. mVirtualCursor = new nsAccessiblePivot(this);
  35. mVirtualCursor->AddObserver(this);
  36. }
  37. return mVirtualCursor;
  38. }
  39. inline void
  40. DocAccessible::FireDelayedEvent(AccEvent* aEvent)
  41. {
  42. #ifdef A11Y_LOG
  43. if (logging::IsEnabled(logging::eDocLoad))
  44. logging::DocLoadEventFired(aEvent);
  45. #endif
  46. mNotificationController->QueueEvent(aEvent);
  47. }
  48. inline void
  49. DocAccessible::FireDelayedEvent(uint32_t aEventType, Accessible* aTarget)
  50. {
  51. RefPtr<AccEvent> event = new AccEvent(aEventType, aTarget);
  52. FireDelayedEvent(event);
  53. }
  54. inline void
  55. DocAccessible::BindChildDocument(DocAccessible* aDocument)
  56. {
  57. mNotificationController->ScheduleChildDocBinding(aDocument);
  58. }
  59. template<class Class, class Arg>
  60. inline void
  61. DocAccessible::HandleNotification(Class* aInstance,
  62. typename TNotification<Class, Arg>::Callback aMethod,
  63. Arg* aArg)
  64. {
  65. if (mNotificationController) {
  66. mNotificationController->HandleNotification<Class, Arg>(aInstance,
  67. aMethod, aArg);
  68. }
  69. }
  70. inline void
  71. DocAccessible::UpdateText(nsIContent* aTextNode)
  72. {
  73. NS_ASSERTION(mNotificationController, "The document was shut down!");
  74. // Ignore the notification if initial tree construction hasn't been done yet.
  75. if (mNotificationController && HasLoadState(eTreeConstructed))
  76. mNotificationController->ScheduleTextUpdate(aTextNode);
  77. }
  78. inline void
  79. DocAccessible::AddScrollListener()
  80. {
  81. // Delay scroll initializing until the document has a root frame.
  82. if (!mPresShell->GetRootFrame())
  83. return;
  84. mDocFlags |= eScrollInitialized;
  85. nsIScrollableFrame* sf = mPresShell->GetRootScrollFrameAsScrollable();
  86. if (sf) {
  87. sf->AddScrollPositionListener(this);
  88. #ifdef A11Y_LOG
  89. if (logging::IsEnabled(logging::eDocCreate))
  90. logging::Text("add scroll listener");
  91. #endif
  92. }
  93. }
  94. inline void
  95. DocAccessible::RemoveScrollListener()
  96. {
  97. nsIScrollableFrame* sf = mPresShell->GetRootScrollFrameAsScrollable();
  98. if (sf)
  99. sf->RemoveScrollPositionListener(this);
  100. }
  101. inline void
  102. DocAccessible::NotifyOfLoad(uint32_t aLoadEventType)
  103. {
  104. mLoadState |= eDOMLoaded;
  105. mLoadEventType = aLoadEventType;
  106. // If the document is loaded completely then network activity was presumingly
  107. // caused by file loading. Fire busy state change event.
  108. if (HasLoadState(eCompletelyLoaded) && IsLoadEventTarget()) {
  109. RefPtr<AccEvent> stateEvent =
  110. new AccStateChangeEvent(this, states::BUSY, false);
  111. FireDelayedEvent(stateEvent);
  112. }
  113. }
  114. inline void
  115. DocAccessible::MaybeNotifyOfValueChange(Accessible* aAccessible)
  116. {
  117. a11y::role role = aAccessible->Role();
  118. if (role == roles::ENTRY || role == roles::COMBOBOX)
  119. FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible);
  120. }
  121. inline Accessible*
  122. DocAccessible::GetAccessibleEvenIfNotInMapOrContainer(nsINode* aNode) const
  123. {
  124. Accessible* acc = GetAccessibleEvenIfNotInMap(aNode);
  125. return acc ? acc : GetContainerAccessible(aNode);
  126. }
  127. inline void
  128. DocAccessible::CreateSubtree(Accessible* aChild)
  129. {
  130. // If a focused node has been shown then it could mean its frame was recreated
  131. // while the node stays focused and we need to fire focus event on
  132. // the accessible we just created. If the queue contains a focus event for
  133. // this node already then it will be suppressed by this one.
  134. Accessible* focusedAcc = nullptr;
  135. CacheChildrenInSubtree(aChild, &focusedAcc);
  136. #ifdef A11Y_LOG
  137. if (logging::IsEnabled(logging::eVerbose)) {
  138. logging::Tree("TREE", "Created subtree", aChild);
  139. }
  140. #endif
  141. // Fire events for ARIA elements.
  142. if (aChild->HasARIARole()) {
  143. roles::Role role = aChild->ARIARole();
  144. if (role == roles::MENUPOPUP) {
  145. FireDelayedEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START, aChild);
  146. }
  147. else if (role == roles::ALERT) {
  148. FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, aChild);
  149. }
  150. }
  151. // XXX: do we really want to send focus to focused DOM node not taking into
  152. // account active item?
  153. if (focusedAcc) {
  154. FocusMgr()->DispatchFocusEvent(this, focusedAcc);
  155. SelectionMgr()->
  156. SetControlSelectionListener(focusedAcc->GetNode()->AsElement());
  157. }
  158. }
  159. } // namespace a11y
  160. } // namespace mozilla
  161. #endif