DocAccessible-inl.h (6033B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_a11y_DocAccessible_inl_h_ 8 #define mozilla_a11y_DocAccessible_inl_h_ 9 10 #include "DocAccessible.h" 11 #include "LocalAccessible-inl.h" 12 #include "nsAccessibilityService.h" 13 #include "NotificationController.h" 14 #include "States.h" 15 #include "mozilla/dom/DocumentInlines.h" 16 17 #ifdef A11Y_LOG 18 # include "Logging.h" 19 #endif 20 21 namespace mozilla { 22 namespace a11y { 23 24 inline LocalAccessible* DocAccessible::AccessibleOrTrueContainer( 25 nsINode* aNode, bool aNoContainerIfPruned) const { 26 // HTML comboboxes have no-content list accessible as an intermediate 27 // containing all options. 28 LocalAccessible* container = 29 GetAccessibleOrContainer(aNode, aNoContainerIfPruned); 30 if (container && container->IsHTMLCombobox()) { 31 return container->LocalFirstChild(); 32 } 33 return container; 34 } 35 36 inline bool DocAccessible::IsContentLoaded() const { 37 // eDOMLoaded flag check is used for error pages as workaround to make this 38 // method return correct result since error pages do not receive 'pageshow' 39 // event and as consequence Document::IsShowing() returns false. 40 return mDocumentNode && mDocumentNode->IsVisible() && 41 (mDocumentNode->IsShowing() || HasLoadState(eDOMLoaded)); 42 } 43 44 inline bool DocAccessible::IsHidden() const { return mDocumentNode->Hidden(); } 45 46 inline void DocAccessible::FireDelayedEvent(AccEvent* aEvent) { 47 #ifdef A11Y_LOG 48 if (logging::IsEnabled(logging::eDocLoad)) logging::DocLoadEventFired(aEvent); 49 #endif 50 51 mNotificationController->QueueEvent(aEvent); 52 } 53 54 inline void DocAccessible::FireDelayedEvent(uint32_t aEventType, 55 LocalAccessible* aTarget) { 56 RefPtr<AccEvent> event = new AccEvent(aEventType, aTarget); 57 FireDelayedEvent(event); 58 } 59 60 inline void DocAccessible::BindChildDocument(DocAccessible* aDocument) { 61 mNotificationController->ScheduleChildDocBinding(aDocument); 62 } 63 64 template <class Class, class... Args> 65 inline void DocAccessible::HandleNotification( 66 Class* aInstance, typename TNotification<Class, Args...>::Callback aMethod, 67 Args*... aArgs) { 68 if (mNotificationController) { 69 mNotificationController->HandleNotification<Class, Args...>( 70 aInstance, aMethod, aArgs...); 71 } 72 } 73 74 inline void DocAccessible::UpdateText(nsIContent* aTextNode) { 75 NS_ASSERTION(mNotificationController, "The document was shut down!"); 76 77 // Ignore the notification if initial tree construction hasn't been done yet. 78 if (mNotificationController && HasLoadState(eTreeConstructed)) { 79 mNotificationController->ScheduleTextUpdate(aTextNode); 80 } 81 } 82 83 inline void DocAccessible::NotifyOfLoad(uint32_t aLoadEventType) { 84 mLoadState |= eDOMLoaded; 85 mLoadEventType = aLoadEventType; 86 87 // If the document is loaded completely then network activity was presumingly 88 // caused by file loading. Fire busy state change event. 89 if (HasLoadState(eCompletelyLoaded) && IsLoadEventTarget()) { 90 RefPtr<AccEvent> stateEvent = 91 new AccStateChangeEvent(this, states::BUSY, false); 92 FireDelayedEvent(stateEvent); 93 } 94 } 95 96 inline void DocAccessible::MaybeNotifyOfValueChange( 97 LocalAccessible* aAccessible) { 98 if (aAccessible->IsCombobox() || aAccessible->Role() == roles::ENTRY || 99 aAccessible->Role() == roles::SPINBUTTON) { 100 FireDelayedEvent(nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE, aAccessible); 101 } 102 } 103 104 inline LocalAccessible* DocAccessible::GetAccessibleEvenIfNotInMapOrContainer( 105 nsINode* aNode) const { 106 LocalAccessible* acc = GetAccessibleEvenIfNotInMap(aNode); 107 return acc ? acc : GetContainerAccessible(aNode); 108 } 109 110 inline void DocAccessible::CreateSubtree(LocalAccessible* aChild) { 111 // If a focused node has been shown then it could mean its frame was recreated 112 // while the node stays focused and we need to fire focus event on 113 // the accessible we just created. If the queue contains a focus event for 114 // this node already then it will be suppressed by this one. 115 LocalAccessible* focusedAcc = nullptr; 116 CacheChildrenInSubtree(aChild, &focusedAcc); 117 118 #ifdef A11Y_LOG 119 if (logging::IsEnabled(logging::eVerbose)) { 120 logging::Tree("TREE", "Created subtree", aChild); 121 } 122 #endif 123 124 // XXX: do we really want to send focus to focused DOM node not taking into 125 // account active item? 126 if (focusedAcc) { 127 FocusMgr()->DispatchFocusEvent(this, focusedAcc); 128 SelectionMgr()->SetControlSelectionListener( 129 focusedAcc->GetNode()->AsElement()); 130 } 131 } 132 133 inline DocAccessible::AttrRelProviders* DocAccessible::GetRelProviders( 134 dom::Element* aElement, const nsAString& aID) const { 135 DependentIDsHashtable* hash = mDependentIDsHashes.Get( 136 aElement->GetUncomposedDocOrConnectedShadowRoot()); 137 if (hash) { 138 return hash->Get(aID); 139 } 140 return nullptr; 141 } 142 143 inline DocAccessible::AttrRelProviders* DocAccessible::GetOrCreateRelProviders( 144 dom::Element* aElement, const nsAString& aID) { 145 dom::DocumentOrShadowRoot* docOrShadowRoot = 146 aElement->GetUncomposedDocOrConnectedShadowRoot(); 147 DependentIDsHashtable* hash = 148 mDependentIDsHashes.GetOrInsertNew(docOrShadowRoot); 149 150 return hash->GetOrInsertNew(aID); 151 } 152 153 inline void DocAccessible::RemoveRelProvidersIfEmpty(dom::Element* aElement, 154 const nsAString& aID) { 155 dom::DocumentOrShadowRoot* docOrShadowRoot = 156 aElement->GetUncomposedDocOrConnectedShadowRoot(); 157 DependentIDsHashtable* hash = mDependentIDsHashes.Get(docOrShadowRoot); 158 if (hash) { 159 AttrRelProviders* providers = hash->Get(aID); 160 if (providers && providers->Length() == 0) { 161 hash->Remove(aID); 162 if (mDependentIDsHashes.IsEmpty()) { 163 mDependentIDsHashes.Remove(docOrShadowRoot); 164 } 165 } 166 } 167 } 168 169 } // namespace a11y 170 } // namespace mozilla 171 172 #endif