2001-12-17 04:21:29 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2001-12-17 04:21:29 +03:00
|
|
|
|
2012-06-11 03:44:50 +04:00
|
|
|
#include "XULTabAccessible.h"
|
2010-04-27 10:52:03 +04:00
|
|
|
|
2018-08-02 09:25:09 +03:00
|
|
|
#include "ARIAMap.h"
|
2010-04-27 10:52:03 +04:00
|
|
|
#include "nsAccUtils.h"
|
2011-08-10 05:44:00 +04:00
|
|
|
#include "Relation.h"
|
2012-01-12 07:07:35 +04:00
|
|
|
#include "Role.h"
|
2011-04-10 03:38:06 +04:00
|
|
|
#include "States.h"
|
2010-04-27 10:52:03 +04:00
|
|
|
|
|
|
|
// NOTE: alphabetically ordered
|
2019-01-02 16:05:23 +03:00
|
|
|
#include "mozilla/dom/Document.h"
|
2001-12-17 04:21:29 +03:00
|
|
|
#include "nsIDOMXULSelectCntrlItemEl.h"
|
2010-05-14 13:55:00 +04:00
|
|
|
#include "nsIDOMXULRelatedElement.h"
|
2017-02-02 18:32:58 +03:00
|
|
|
#include "nsXULElement.h"
|
|
|
|
|
|
|
|
#include "mozilla/dom/BindingDeclarations.h"
|
2001-12-17 04:21:29 +03:00
|
|
|
|
2011-07-27 16:43:01 +04:00
|
|
|
using namespace mozilla::a11y;
|
|
|
|
|
2010-01-19 07:35:08 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-11 03:44:50 +04:00
|
|
|
// XULTabAccessible
|
2010-01-19 07:35:08 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2012-06-11 03:44:50 +04:00
|
|
|
XULTabAccessible::XULTabAccessible(nsIContent* aContent, DocAccessible* aDoc)
|
2017-01-25 21:31:56 +03:00
|
|
|
: HyperTextAccessibleWrap(aContent, aDoc) {}
|
2001-12-17 04:21:29 +03:00
|
|
|
|
2010-01-19 07:35:08 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2014-10-22 04:49:28 +04:00
|
|
|
// XULTabAccessible: Accessible
|
2010-01-19 07:35:08 +03:00
|
|
|
|
2018-05-15 20:40:22 +03:00
|
|
|
uint8_t XULTabAccessible::ActionCount() const { return 1; }
|
2001-12-17 04:21:29 +03:00
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
void XULTabAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
|
|
|
|
if (aIndex == eAction_Switch) aName.AssignLiteral("switch");
|
2001-12-17 04:21:29 +03:00
|
|
|
}
|
|
|
|
|
2018-05-15 20:40:22 +03:00
|
|
|
bool XULTabAccessible::DoAction(uint8_t index) const {
|
2001-12-17 04:21:29 +03:00
|
|
|
if (index == eAction_Switch) {
|
2017-02-02 18:32:58 +03:00
|
|
|
// XXXbz Could this just FromContent?
|
2018-03-22 00:39:04 +03:00
|
|
|
RefPtr<nsXULElement> tab = nsXULElement::FromNodeOrNull(mContent);
|
2014-09-16 21:30:23 +04:00
|
|
|
if (tab) {
|
2017-02-02 18:32:58 +03:00
|
|
|
tab->Click(mozilla::dom::CallerType::System);
|
2014-09-16 21:30:23 +04:00
|
|
|
return true;
|
2001-12-17 04:21:29 +03:00
|
|
|
}
|
|
|
|
}
|
2014-09-16 21:30:23 +04:00
|
|
|
return false;
|
2001-12-17 04:21:29 +03:00
|
|
|
}
|
|
|
|
|
2010-01-19 07:35:08 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-11 03:44:50 +04:00
|
|
|
// XULTabAccessible: Accessible
|
2010-01-19 07:35:08 +03:00
|
|
|
|
2018-05-07 22:05:50 +03:00
|
|
|
role XULTabAccessible::NativeRole() const { return roles::PAGETAB; }
|
2001-12-17 04:21:29 +03:00
|
|
|
|
2018-05-15 21:04:50 +03:00
|
|
|
uint64_t XULTabAccessible::NativeState() const {
|
2010-01-19 07:35:08 +03:00
|
|
|
// Possible states: focused, focusable, unavailable(disabled), offscreen.
|
|
|
|
|
2001-12-17 04:21:29 +03:00
|
|
|
// get focus and disable status from base class
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t state = AccessibleWrap::NativeState();
|
2002-06-21 08:41:28 +04:00
|
|
|
|
2013-06-05 19:03:52 +04:00
|
|
|
// Check whether the tab is selected and/or pinned
|
2018-12-04 19:32:15 +03:00
|
|
|
nsCOMPtr<nsIDOMXULSelectControlItemElement> tab =
|
|
|
|
Elm()->AsXULSelectControlItem();
|
2005-02-01 06:43:37 +03:00
|
|
|
if (tab) {
|
2011-09-29 10:19:26 +04:00
|
|
|
bool selected = false;
|
2021-02-20 02:14:32 +03:00
|
|
|
if (NS_SUCCEEDED(tab->GetSelected(&selected)) && selected) {
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::SELECTED;
|
2021-02-20 02:14:32 +03:00
|
|
|
}
|
2013-06-05 19:03:52 +04:00
|
|
|
|
2017-12-07 21:13:50 +03:00
|
|
|
if (mContent->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::pinned,
|
2021-02-20 02:14:32 +03:00
|
|
|
nsGkAtoms::_true, eCaseMatters)) {
|
2013-06-05 19:03:52 +04:00
|
|
|
state |= states::PINNED;
|
2021-02-20 02:14:32 +03:00
|
|
|
}
|
2005-02-01 06:43:37 +03:00
|
|
|
}
|
2013-06-05 19:03:52 +04:00
|
|
|
|
2011-04-10 03:38:06 +04:00
|
|
|
return state;
|
2001-12-17 04:21:29 +03:00
|
|
|
}
|
|
|
|
|
2012-06-11 03:44:50 +04:00
|
|
|
uint64_t XULTabAccessible::NativeInteractiveState() const {
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t state = Accessible::NativeInteractiveState();
|
2012-06-04 09:41:06 +04:00
|
|
|
return (state & states::UNAVAILABLE) ? state : state | states::SELECTABLE;
|
|
|
|
}
|
|
|
|
|
2018-05-15 16:47:10 +03:00
|
|
|
Relation XULTabAccessible::RelationByType(RelationType aType) const {
|
2012-05-29 05:18:45 +04:00
|
|
|
Relation rel = AccessibleWrap::RelationByType(aType);
|
2013-10-19 22:19:50 +04:00
|
|
|
if (aType != RelationType::LABEL_FOR) return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
|
|
|
|
// Expose 'LABEL_FOR' relation on tab accessible for tabpanel accessible.
|
2019-06-21 00:09:37 +03:00
|
|
|
ErrorResult rv;
|
2020-12-23 08:42:00 +03:00
|
|
|
nsIContent* parent = mContent->AsElement()->Closest("tabs"_ns, rv);
|
2018-12-04 19:32:15 +03:00
|
|
|
if (!parent) return rel;
|
|
|
|
|
2010-05-14 13:55:00 +04:00
|
|
|
nsCOMPtr<nsIDOMXULRelatedElement> tabsElm =
|
2018-12-04 19:32:15 +03:00
|
|
|
parent->AsElement()->AsXULRelated();
|
2010-05-14 13:55:00 +04:00
|
|
|
if (!tabsElm) return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
RefPtr<mozilla::dom::Element> tabpanelElement;
|
|
|
|
tabsElm->GetRelatedElement(GetNode(), getter_AddRefs(tabpanelElement));
|
|
|
|
if (!tabpanelElement) return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
rel.AppendTarget(mDoc, tabpanelElement);
|
2011-08-10 05:44:00 +04:00
|
|
|
return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
}
|
|
|
|
|
2018-08-02 09:25:09 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2007-03-27 16:17:11 +04:00
|
|
|
|
2010-01-06 13:36:50 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-11 03:44:50 +04:00
|
|
|
// XULTabsAccessible
|
2010-01-06 13:36:50 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2007-03-27 16:17:11 +04:00
|
|
|
|
2012-06-11 03:44:50 +04:00
|
|
|
XULTabsAccessible::XULTabsAccessible(nsIContent* aContent, DocAccessible* aDoc)
|
2012-02-08 02:38:54 +04:00
|
|
|
: XULSelectControlAccessible(aContent, aDoc) {}
|
2001-12-17 04:21:29 +03:00
|
|
|
|
2018-05-07 22:05:50 +03:00
|
|
|
role XULTabsAccessible::NativeRole() const { return roles::PAGETABLIST; }
|
2003-06-02 12:32:46 +04:00
|
|
|
|
2018-05-15 20:40:22 +03:00
|
|
|
uint8_t XULTabsAccessible::ActionCount() const { return 0; }
|
2003-06-02 12:32:46 +04:00
|
|
|
|
2018-05-15 19:55:28 +03:00
|
|
|
void XULTabsAccessible::Value(nsString& aValue) const { aValue.Truncate(); }
|
2003-06-02 12:32:46 +04:00
|
|
|
|
2018-05-15 19:13:02 +03:00
|
|
|
ENameValueFlag XULTabsAccessible::NativeName(nsString& aName) const {
|
2008-10-10 16:26:55 +04:00
|
|
|
// no name
|
2012-10-14 08:18:39 +04:00
|
|
|
return eNameOK;
|
2003-06-02 12:32:46 +04:00
|
|
|
}
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-08-02 09:25:09 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-08-03 06:31:43 +03:00
|
|
|
// XUL tabs is a single selection control and doesn't allow ARIA selection.
|
|
|
|
// However, if aria-multiselectable is used, it becomes a multiselectable
|
|
|
|
// control, where both native and ARIA markup are used to set selection.
|
|
|
|
// Therefore, if aria-multiselectable is set, use the base implementation of
|
|
|
|
// the selection retrieval methods in order to support ARIA selection.
|
|
|
|
// We don't bother overriding the selection setting methods because
|
|
|
|
// current front-end code using XUL tabs doesn't support setting of
|
|
|
|
// aria-selected by the a11y engine and we still want to be able to set the
|
|
|
|
// primary selected item according to XUL.
|
|
|
|
|
|
|
|
void XULTabsAccessible::SelectedItems(nsTArray<Accessible*>* aItems) {
|
|
|
|
if (nsAccUtils::IsARIAMultiSelectable(this)) {
|
|
|
|
AccessibleWrap::SelectedItems(aItems);
|
|
|
|
} else {
|
|
|
|
XULSelectControlAccessible::SelectedItems(aItems);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Accessible* XULTabsAccessible::GetSelectedItem(uint32_t aIndex) {
|
|
|
|
if (nsAccUtils::IsARIAMultiSelectable(this)) {
|
|
|
|
return AccessibleWrap::GetSelectedItem(aIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
return XULSelectControlAccessible::GetSelectedItem(aIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t XULTabsAccessible::SelectedItemCount() {
|
|
|
|
if (nsAccUtils::IsARIAMultiSelectable(this)) {
|
|
|
|
return AccessibleWrap::SelectedItemCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
return XULSelectControlAccessible::SelectedItemCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool XULTabsAccessible::IsItemSelected(uint32_t aIndex) {
|
|
|
|
if (nsAccUtils::IsARIAMultiSelectable(this)) {
|
|
|
|
return AccessibleWrap::IsItemSelected(aIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
return XULSelectControlAccessible::IsItemSelected(aIndex);
|
|
|
|
}
|
|
|
|
|
2010-05-14 13:55:00 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-12-28 12:15:02 +04:00
|
|
|
// XULTabpanelsAccessible
|
2010-05-14 13:55:00 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-05-07 22:05:50 +03:00
|
|
|
role XULTabpanelsAccessible::NativeRole() const { return roles::PANE; }
|
2010-05-14 13:55:00 +04:00
|
|
|
|
2007-11-12 09:02:42 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-11 03:44:50 +04:00
|
|
|
// XULTabpanelAccessible
|
2010-05-14 13:55:00 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2012-06-11 03:44:50 +04:00
|
|
|
XULTabpanelAccessible::XULTabpanelAccessible(nsIContent* aContent,
|
|
|
|
DocAccessible* aDoc)
|
2012-05-29 05:18:45 +04:00
|
|
|
: AccessibleWrap(aContent, aDoc) {}
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-05-07 22:05:50 +03:00
|
|
|
role XULTabpanelAccessible::NativeRole() const { return roles::PROPERTYPAGE; }
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-05-15 16:47:10 +03:00
|
|
|
Relation XULTabpanelAccessible::RelationByType(RelationType aType) const {
|
2012-05-29 05:18:45 +04:00
|
|
|
Relation rel = AccessibleWrap::RelationByType(aType);
|
2013-10-19 22:19:50 +04:00
|
|
|
if (aType != RelationType::LABELLED_BY) return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
|
|
|
|
// Expose 'LABELLED_BY' relation on tabpanel accessible for tab accessible.
|
2018-12-04 19:32:15 +03:00
|
|
|
if (!mContent->GetParent()) return rel;
|
|
|
|
|
2010-05-14 13:55:00 +04:00
|
|
|
nsCOMPtr<nsIDOMXULRelatedElement> tabpanelsElm =
|
2018-12-04 19:32:15 +03:00
|
|
|
mContent->GetParent()->AsElement()->AsXULRelated();
|
2010-05-14 13:55:00 +04:00
|
|
|
if (!tabpanelsElm) return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
RefPtr<mozilla::dom::Element> tabElement;
|
|
|
|
tabpanelsElm->GetRelatedElement(GetNode(), getter_AddRefs(tabElement));
|
|
|
|
if (!tabElement) return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
|
2018-05-30 05:58:47 +03:00
|
|
|
rel.AppendTarget(mDoc, tabElement);
|
2011-08-10 05:44:00 +04:00
|
|
|
return rel;
|
2007-11-12 09:02:42 +03:00
|
|
|
}
|