diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 43f2b0acebf..af74bd51a48 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -2234,6 +2234,29 @@ nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState) // Apply ARIA states to be sure accessible states will be overriden. *aState |= GetARIAState(); + if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) { + if (*aState & nsIAccessibleStates::STATE_FOCUSED) { + *aState |= nsIAccessibleStates::STATE_SELECTED; + } else { + // Expose 'selected' state on ARIA tab if the focus is on internal element + // of related tabpanel. + nsCOMPtr tabPanel; + rv = GetAccessibleRelated(nsIAccessibleRelation::RELATION_LABEL_FOR, + getter_AddRefs(tabPanel)); + NS_ENSURE_SUCCESS(rv, rv); + + if (tabPanel && Role(tabPanel) == nsIAccessibleRole::ROLE_PROPERTYPAGE) { + nsCOMPtr tabPanelAccessNode(do_QueryInterface(tabPanel)); + nsCOMPtr tabPanelNode; + tabPanelAccessNode->GetDOMNode(getter_AddRefs(tabPanelNode)); + NS_ENSURE_STATE(tabPanelNode); + + if (nsAccUtils::IsAncestorOf(tabPanelNode, gLastFocusedNode)) + *aState |= nsIAccessibleStates::STATE_SELECTED; + } + } + } + // Set additional states which presence depends on another states. if (!aExtraState) return NS_OK;