Bug 1480058 part 1: Expose states for aria-selected/aria-multiselectable on XUL tab/tabs. r?surkov
MozReview-Commit-ID: JeV5vBffQIq
--- a/accessible/tests/mochitest/states/test_aria.xul
+++ b/accessible/tests/mochitest/states/test_aria.xul
@@ -19,16 +19,24 @@
<script type="application/javascript">
<![CDATA[
function doTest()
{
// aria-pressed
testStates("pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE);
testStates("pressed_menu_button", STATE_PRESSED | STATE_HASPOPUP, 0, STATE_CHECKABLE);
+ testStates("tabs", STATE_MULTISELECTABLE);
+ // Make sure XUL selection works, since aria-selected defaults to false.
+ testStates("tab1", STATE_SELECTED);
+ // aria-selected="true".
+ testStates("tab2", STATE_SELECTED);
+ // Neither.
+ testStates("tab3", 0, 0, STATE_SELECTED);
+
SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
@@ -48,13 +56,21 @@
<vbox flex="1">
<button id="pressed_button" aria-pressed="true" label="I am pressed" />
<button id="pressed_menu_button" aria-pressed="true" label="I am pressed" type="menu-button">
<menupopup>
<menuitem label="I am a menu item" />
</menupopup>
</button>
+
+ <tabbox>
+ <tabs id="tabs" aria-multiselectable="true">
+ <tab id="tab1" label="tab1" selected="true"/>
+ <tab id="tab2" label="tab2" aria-selected="true"/>
+ <tab id="tab3" label="tab3"/>
+ </tabs>
+ </tabbox>
</vbox>
</hbox>
</window>
--- a/accessible/xul/XULTabAccessible.cpp
+++ b/accessible/xul/XULTabAccessible.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "XULTabAccessible.h"
+#include "ARIAMap.h"
#include "nsAccUtils.h"
#include "Relation.h"
#include "Role.h"
#include "States.h"
// NOTE: alphabetically ordered
#include "nsIDocument.h"
#include "nsIDOMXULSelectCntrlEl.h"
@@ -118,16 +119,27 @@ XULTabAccessible::RelationByType(Relatio
tabsElm->GetRelatedElement(GetNode(), getter_AddRefs(tabpanelElement));
if (!tabpanelElement)
return rel;
rel.AppendTarget(mDoc, tabpanelElement);
return rel;
}
+void
+XULTabAccessible::ApplyARIAState(uint64_t* aState) const
+{
+ HyperTextAccessibleWrap::ApplyARIAState(aState);
+ // XUL tab has an implicit ARIA role of tab, so support aria-selected.
+ // Don't use aria::MapToState because that will set the SELECTABLE state
+ // even if the tab is disabled.
+ if (nsAccUtils::IsARIASelected(this)) {
+ *aState |= states::SELECTED;
+ }
+}
////////////////////////////////////////////////////////////////////////////////
// XULTabsAccessible
////////////////////////////////////////////////////////////////////////////////
XULTabsAccessible::
XULTabsAccessible(nsIContent* aContent, DocAccessible* aDoc) :
XULSelectControlAccessible(aContent, aDoc)
@@ -154,16 +166,26 @@ XULTabsAccessible::Value(nsString& aValu
ENameValueFlag
XULTabsAccessible::NativeName(nsString& aName) const
{
// no name
return eNameOK;
}
+void
+XULTabsAccessible::ApplyARIAState(uint64_t* aState) const
+{
+ XULSelectControlAccessible::ApplyARIAState(aState);
+ // XUL tabs has an implicit ARIA role of tablist, so support
+ // aria-multiselectable.
+ MOZ_ASSERT(Elm());
+ aria::MapToState(aria::eARIAMultiSelectable, Elm(), aState);
+}
+
////////////////////////////////////////////////////////////////////////////////
// XULTabpanelsAccessible
////////////////////////////////////////////////////////////////////////////////
role
XULTabpanelsAccessible::NativeRole() const
{
--- a/accessible/xul/XULTabAccessible.h
+++ b/accessible/xul/XULTabAccessible.h
@@ -24,16 +24,17 @@ public:
XULTabAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual a11y::role NativeRole() const override;
virtual uint64_t NativeState() const override;
virtual uint64_t NativeInteractiveState() const override;
virtual Relation RelationByType(RelationType aType) const override;
+ virtual void ApplyARIAState(uint64_t* aState) const override;
// ActionAccessible
virtual uint8_t ActionCount() const override;
virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
virtual bool DoAction(uint8_t aIndex) const override;
};
@@ -43,16 +44,17 @@ public:
class XULTabsAccessible : public XULSelectControlAccessible
{
public:
XULTabsAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual void Value(nsString& aValue) const override;
virtual a11y::role NativeRole() const override;
+ virtual void ApplyARIAState(uint64_t* aState) const override;
// ActionAccessible
virtual uint8_t ActionCount() const override;
protected:
// Accessible
virtual ENameValueFlag NativeName(nsString& aName) const override;
};