2001-09-25 04:48:50 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; 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-06-30 04:25:09 +04:00
|
|
|
|
2012-06-06 14:27:46 +04:00
|
|
|
#include "HTMLSelectAccessible.h"
|
2010-04-27 10:52:03 +04:00
|
|
|
|
2012-04-13 18:17:03 +04:00
|
|
|
#include "Accessible-inl.h"
|
2010-04-27 10:52:03 +04:00
|
|
|
#include "nsAccessibilityService.h"
|
|
|
|
#include "nsAccUtils.h"
|
2012-05-27 13:01:40 +04:00
|
|
|
#include "DocAccessible.h"
|
2010-04-27 10:52:03 +04:00
|
|
|
#include "nsEventShell.h"
|
|
|
|
#include "nsTextEquivUtils.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
|
|
|
|
|
|
|
#include "nsCOMPtr.h"
|
2013-02-18 16:24:58 +04:00
|
|
|
#include "mozilla/dom/HTMLOptionElement.h"
|
2016-07-01 05:59:38 +03:00
|
|
|
#include "mozilla/dom/HTMLSelectElement.h"
|
2006-02-27 07:13:51 +03:00
|
|
|
#include "nsIComboboxControlFrame.h"
|
2014-05-25 02:20:39 +04:00
|
|
|
#include "nsContainerFrame.h"
|
2001-11-07 03:12:16 +03:00
|
|
|
#include "nsIListControlFrame.h"
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2011-07-27 16:43:01 +04:00
|
|
|
using namespace mozilla::a11y;
|
2013-02-18 16:24:58 +04:00
|
|
|
using namespace mozilla::dom;
|
2011-07-27 16:43:01 +04:00
|
|
|
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectListAccessible
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2001-11-07 03:12:16 +03:00
|
|
|
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectListAccessible::
|
|
|
|
HTMLSelectListAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
2012-05-29 05:18:45 +04:00
|
|
|
AccessibleWrap(aContent, aDoc)
|
2001-06-30 04:25:09 +04:00
|
|
|
{
|
2012-12-18 09:22:26 +04:00
|
|
|
mGenericTypes |= eListControl | eSelect;
|
2001-11-07 03:12:16 +03:00
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectListAccessible: Accessible public
|
2009-12-10 22:12:19 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t
|
2018-05-15 21:04:50 +03:00
|
|
|
HTMLSelectListAccessible::NativeState() const
|
2001-11-07 03:12:16 +03:00
|
|
|
{
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t state = AccessibleWrap::NativeState();
|
2017-12-07 21:13:50 +03:00
|
|
|
if (mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple))
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::MULTISELECTABLE | states::EXTSELECTABLE;
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2011-04-10 03:38:06 +04:00
|
|
|
return state;
|
2001-11-07 03:12:16 +03:00
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2012-01-12 07:07:35 +04:00
|
|
|
role
|
2018-05-07 22:05:50 +03:00
|
|
|
HTMLSelectListAccessible::NativeRole() const
|
2003-02-27 04:51:13 +03:00
|
|
|
{
|
2012-01-12 07:07:35 +04:00
|
|
|
return roles::LISTBOX;
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
|
|
|
|
2010-09-02 04:46:59 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectListAccessible: SelectAccessible
|
2010-09-02 04:46:59 +04:00
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectListAccessible::SelectAll()
|
2010-09-02 04:46:59 +04:00
|
|
|
{
|
2017-12-07 21:13:50 +03:00
|
|
|
return mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
|
2012-05-29 05:18:45 +04:00
|
|
|
AccessibleWrap::SelectAll() : false;
|
2010-09-02 04:46:59 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectListAccessible::UnselectAll()
|
2010-09-02 04:46:59 +04:00
|
|
|
{
|
2017-12-07 21:13:50 +03:00
|
|
|
return mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
|
2012-05-29 05:18:45 +04:00
|
|
|
AccessibleWrap::UnselectAll() : false;
|
2010-09-02 04:46:59 +04:00
|
|
|
}
|
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectListAccessible: Widgets
|
2011-09-28 05:46:11 +04:00
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectListAccessible::IsWidget() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectListAccessible::IsActiveWidget() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
return FocusMgr()->HasDOMFocus(mContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectListAccessible::AreItemsOperable() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible*
|
2018-05-13 12:26:02 +03:00
|
|
|
HTMLSelectListAccessible::CurrentItem() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
nsIListControlFrame* listControlFrame = do_QueryFrame(GetFrame());
|
|
|
|
if (listControlFrame) {
|
|
|
|
nsCOMPtr<nsIContent> activeOptionNode = listControlFrame->GetCurrentOption();
|
|
|
|
if (activeOptionNode) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = Document();
|
2011-09-28 05:46:11 +04:00
|
|
|
if (document)
|
|
|
|
return document->GetAccessible(activeOptionNode);
|
|
|
|
}
|
|
|
|
}
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2011-09-28 05:46:11 +04:00
|
|
|
}
|
|
|
|
|
2011-12-08 16:20:15 +04:00
|
|
|
void
|
2018-05-13 13:14:55 +03:00
|
|
|
HTMLSelectListAccessible::SetCurrentItem(const Accessible* aItem)
|
2011-12-08 16:20:15 +04:00
|
|
|
{
|
2017-12-05 20:05:51 +03:00
|
|
|
if (!aItem->GetContent()->IsElement())
|
|
|
|
return;
|
|
|
|
|
|
|
|
aItem->GetContent()->AsElement()->SetAttr(kNameSpaceID_None,
|
|
|
|
nsGkAtoms::selected,
|
|
|
|
NS_LITERAL_STRING("true"),
|
|
|
|
true);
|
2011-12-08 16:20:15 +04:00
|
|
|
}
|
|
|
|
|
2016-02-26 18:25:36 +03:00
|
|
|
bool
|
|
|
|
HTMLSelectListAccessible::IsAcceptableChild(nsIContent* aEl) const
|
2009-12-10 22:12:19 +03:00
|
|
|
{
|
2016-02-26 18:25:36 +03:00
|
|
|
return aEl->IsAnyOfHTMLElements(nsGkAtoms::option, nsGkAtoms::optgroup);
|
2009-11-19 19:35:38 +03:00
|
|
|
}
|
|
|
|
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectOptionAccessible
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectOptionAccessible::
|
|
|
|
HTMLSelectOptionAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
2012-05-31 12:04:41 +04:00
|
|
|
HyperTextAccessibleWrap(aContent, aDoc)
|
2001-11-07 03:12:16 +03:00
|
|
|
{
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
|
|
|
|
2010-01-06 13:36:50 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectOptionAccessible: Accessible public
|
2010-01-06 13:36:50 +03:00
|
|
|
|
2012-01-12 07:07:35 +04:00
|
|
|
role
|
2018-05-07 22:05:50 +03:00
|
|
|
HTMLSelectOptionAccessible::NativeRole() const
|
2003-02-27 04:51:13 +03:00
|
|
|
{
|
2012-11-10 13:41:40 +04:00
|
|
|
if (GetCombobox())
|
2012-01-12 07:07:35 +04:00
|
|
|
return roles::COMBOBOX_OPTION;
|
2008-10-17 14:10:43 +04:00
|
|
|
|
2012-01-12 07:07:35 +04:00
|
|
|
return roles::OPTION;
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
|
|
|
|
2012-10-14 08:18:39 +04:00
|
|
|
ENameValueFlag
|
2018-05-15 19:13:02 +03:00
|
|
|
HTMLSelectOptionAccessible::NativeName(nsString& aName) const
|
2003-02-27 04:51:13 +03:00
|
|
|
{
|
|
|
|
// CASE #1 -- great majority of the cases
|
|
|
|
// find the label attribute - this is what the W3C says we should use
|
2017-12-07 21:13:50 +03:00
|
|
|
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
|
2008-10-10 16:26:55 +04:00
|
|
|
if (!aName.IsEmpty())
|
2012-10-14 08:18:39 +04:00
|
|
|
return eNameOK;
|
2010-06-11 12:23:18 +04:00
|
|
|
|
2017-07-06 15:00:35 +03:00
|
|
|
// CASE #2 -- no label parameter, get the first child,
|
2003-02-27 04:51:13 +03:00
|
|
|
// use it if it is a text node
|
2011-12-07 11:20:17 +04:00
|
|
|
nsIContent* text = mContent->GetFirstChild();
|
2018-04-13 01:41:00 +03:00
|
|
|
if (text && text->IsText()) {
|
2012-10-14 08:18:39 +04:00
|
|
|
nsTextEquivUtils::AppendTextEquivFromTextContent(text, &aName);
|
|
|
|
aName.CompressWhitespace();
|
2012-10-17 10:38:16 +04:00
|
|
|
return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
2008-10-10 16:26:55 +04:00
|
|
|
|
2012-10-14 08:18:39 +04:00
|
|
|
return eNameOK;
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t
|
2018-05-15 21:04:50 +03:00
|
|
|
HTMLSelectOptionAccessible::NativeState() const
|
2001-06-30 04:25:09 +04:00
|
|
|
{
|
2012-06-06 14:27:46 +04:00
|
|
|
// As a HTMLSelectOptionAccessible we can have the following states:
|
2011-04-10 03:38:06 +04:00
|
|
|
// SELECTABLE, SELECTED, FOCUSED, FOCUSABLE, OFFSCREEN
|
2012-05-31 12:04:41 +04:00
|
|
|
// Upcall to Accessible, but skip HyperTextAccessible impl
|
2011-04-10 03:38:06 +04:00
|
|
|
// because we don't want EDITABLE or SELECTABLE_TEXT
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t state = Accessible::NativeState();
|
2011-04-10 03:38:06 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* select = GetSelect();
|
2012-05-11 07:50:03 +04:00
|
|
|
if (!select)
|
|
|
|
return state;
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t selectState = select->State();
|
2012-05-11 07:50:03 +04:00
|
|
|
if (selectState & states::INVISIBLE)
|
2011-04-10 03:38:06 +04:00
|
|
|
return state;
|
2007-06-06 00:02:35 +04:00
|
|
|
|
2001-11-07 03:12:16 +03:00
|
|
|
// Are we selected?
|
2018-03-22 00:39:04 +03:00
|
|
|
HTMLOptionElement* option = HTMLOptionElement::FromNode(mContent);
|
2012-06-02 23:41:29 +04:00
|
|
|
bool selected = option && option->Selected();
|
|
|
|
if (selected)
|
|
|
|
state |= states::SELECTED;
|
2001-11-07 03:12:16 +03:00
|
|
|
|
2011-04-10 03:38:06 +04:00
|
|
|
if (selectState & states::OFFSCREEN) {
|
|
|
|
state |= states::OFFSCREEN;
|
2012-06-02 23:41:29 +04:00
|
|
|
} else if (selectState & states::COLLAPSED) {
|
2011-04-10 03:38:06 +04:00
|
|
|
// <select> is COLLAPSED: add OFFSCREEN, if not the currently
|
2007-06-06 00:02:35 +04:00
|
|
|
// visible option
|
2012-06-02 23:41:29 +04:00
|
|
|
if (!selected) {
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::OFFSCREEN;
|
2018-04-12 09:32:19 +03:00
|
|
|
// Ensure the invisible state is removed. Otherwise, group info will skip
|
|
|
|
// this option. Furthermore, this gets cached and this doesn't get
|
|
|
|
// invalidated even once the select is expanded.
|
|
|
|
state &= ~states::INVISIBLE;
|
2012-06-02 23:41:29 +04:00
|
|
|
} else {
|
2007-06-06 00:02:35 +04:00
|
|
|
// Clear offscreen and invisible for currently showing option
|
2011-04-10 03:38:06 +04:00
|
|
|
state &= ~(states::OFFSCREEN | states::INVISIBLE);
|
|
|
|
state |= selectState & states::OPAQUE1;
|
2007-06-06 00:02:35 +04:00
|
|
|
}
|
2012-06-02 23:41:29 +04:00
|
|
|
} else {
|
2012-05-29 05:18:45 +04:00
|
|
|
// XXX list frames are weird, don't rely on Accessible's general
|
2007-05-16 17:59:06 +04:00
|
|
|
// visibility implementation unless they get reimplemented in layout
|
2011-04-10 03:38:06 +04:00
|
|
|
state &= ~states::OFFSCREEN;
|
|
|
|
// <select> is not collapsed: compare bounds to calculate OFFSCREEN
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* listAcc = Parent();
|
2010-01-11 17:14:06 +03:00
|
|
|
if (listAcc) {
|
2014-09-16 21:30:23 +04:00
|
|
|
nsIntRect optionRect = Bounds();
|
|
|
|
nsIntRect listRect = listAcc->Bounds();
|
2018-01-12 20:07:29 +03:00
|
|
|
if (optionRect.Y() < listRect.Y() ||
|
|
|
|
optionRect.YMost() > listRect.YMost()) {
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::OFFSCREEN;
|
2007-05-07 07:12:00 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-16 21:30:23 +04:00
|
|
|
|
2011-04-10 03:38:06 +04:00
|
|
|
return state;
|
2001-11-07 03:12:16 +03:00
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectOptionAccessible::NativeInteractiveState() const
|
2012-06-04 09:41:06 +04:00
|
|
|
{
|
|
|
|
return NativelyUnavailable() ?
|
|
|
|
states::UNAVAILABLE : states::FOCUSABLE | states::SELECTABLE;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectOptionAccessible::GetLevelInternal()
|
2010-01-06 13:36:50 +03:00
|
|
|
{
|
2013-02-18 16:24:58 +04:00
|
|
|
nsIContent* parentContent = mContent->GetParent();
|
2010-01-06 13:36:50 +03:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
int32_t level =
|
2011-06-04 01:35:17 +04:00
|
|
|
parentContent->NodeInfo()->Equals(nsGkAtoms::optgroup) ? 2 : 1;
|
2010-01-06 13:36:50 +03:00
|
|
|
|
2012-01-12 07:07:35 +04:00
|
|
|
if (level == 1 && Role() != roles::HEADING)
|
2010-01-06 13:36:50 +03:00
|
|
|
level = 0; // In a single level list, the level is irrelevant
|
|
|
|
|
|
|
|
return level;
|
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
nsRect
|
|
|
|
HTMLSelectOptionAccessible::RelativeBounds(nsIFrame** aBoundingFrame) const
|
2012-05-08 04:00:36 +04:00
|
|
|
{
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* combobox = GetCombobox();
|
2012-05-08 04:00:36 +04:00
|
|
|
if (combobox && (combobox->State() & states::COLLAPSED))
|
2014-09-16 21:30:23 +04:00
|
|
|
return combobox->RelativeBounds(aBoundingFrame);
|
|
|
|
|
|
|
|
return HyperTextAccessibleWrap::RelativeBounds(aBoundingFrame);
|
2012-05-08 04:00:36 +04:00
|
|
|
}
|
2010-01-06 13:36:50 +03:00
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
void
|
|
|
|
HTMLSelectOptionAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
|
2002-04-26 08:50:21 +04:00
|
|
|
{
|
2014-09-16 21:30:23 +04:00
|
|
|
if (aIndex == eAction_Select)
|
|
|
|
aName.AssignLiteral("select");
|
2002-04-26 08:50:21 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint8_t
|
2018-05-15 20:40:22 +03:00
|
|
|
HTMLSelectOptionAccessible::ActionCount() const
|
2002-04-26 08:50:21 +04:00
|
|
|
{
|
2011-06-05 23:35:43 +04:00
|
|
|
return 1;
|
2002-04-26 08:50:21 +04:00
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
bool
|
2018-05-15 20:40:22 +03:00
|
|
|
HTMLSelectOptionAccessible::DoAction(uint8_t aIndex) const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
if (aIndex != eAction_Select)
|
2014-09-16 21:30:23 +04:00
|
|
|
return false;
|
2011-09-28 05:46:11 +04:00
|
|
|
|
|
|
|
DoCommand();
|
2014-09-16 21:30:23 +04:00
|
|
|
return true;
|
2002-04-26 08:50:21 +04:00
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
void
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectOptionAccessible::SetSelected(bool aSelect)
|
2010-09-02 04:46:59 +04:00
|
|
|
{
|
2018-03-22 00:39:04 +03:00
|
|
|
HTMLOptionElement* option = HTMLOptionElement::FromNode(mContent);
|
2014-09-16 21:30:23 +04:00
|
|
|
if (option)
|
|
|
|
option->SetSelected(aSelect);
|
2010-09-02 04:46:59 +04:00
|
|
|
}
|
|
|
|
|
2010-01-06 13:36:50 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectOptionAccessible: Widgets
|
2010-01-06 13:36:50 +03:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible*
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectOptionAccessible::ContainerWidget() const
|
2001-11-07 03:12:16 +03:00
|
|
|
{
|
2012-11-10 13:41:40 +04:00
|
|
|
Accessible* parent = Parent();
|
|
|
|
if (parent && parent->IsHTMLOptGroup())
|
|
|
|
parent = parent->Parent();
|
|
|
|
|
|
|
|
return parent && parent->IsListControl() ? parent : nullptr;
|
2005-07-26 01:40:31 +04:00
|
|
|
}
|
|
|
|
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLSelectOptGroupAccessible
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2002-04-06 04:58:46 +04:00
|
|
|
|
2012-01-12 07:07:35 +04:00
|
|
|
role
|
2018-05-07 22:05:50 +03:00
|
|
|
HTMLSelectOptGroupAccessible::NativeRole() const
|
2007-04-25 19:11:02 +04:00
|
|
|
{
|
2012-11-10 13:41:40 +04:00
|
|
|
return roles::GROUPING;
|
2007-04-25 19:11:02 +04:00
|
|
|
}
|
2002-04-06 04:58:46 +04:00
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLSelectOptGroupAccessible::NativeInteractiveState() const
|
2002-04-06 04:58:46 +04:00
|
|
|
{
|
2012-06-04 09:41:06 +04:00
|
|
|
return NativelyUnavailable() ? states::UNAVAILABLE : 0;
|
2002-04-06 04:58:46 +04:00
|
|
|
}
|
|
|
|
|
2017-09-13 21:04:00 +03:00
|
|
|
bool
|
|
|
|
HTMLSelectOptGroupAccessible::IsAcceptableChild(nsIContent* aEl) const
|
|
|
|
{
|
2018-04-15 13:46:24 +03:00
|
|
|
return aEl->IsCharacterData() || aEl->IsHTMLElement(nsGkAtoms::option);
|
2017-09-13 21:04:00 +03:00
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
uint8_t
|
2018-05-15 20:40:22 +03:00
|
|
|
HTMLSelectOptGroupAccessible::ActionCount() const
|
2002-04-26 08:50:21 +04:00
|
|
|
{
|
2014-09-16 21:30:23 +04:00
|
|
|
return 0;
|
2002-04-26 08:50:21 +04:00
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
void
|
|
|
|
HTMLSelectOptGroupAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
|
2002-04-26 08:50:21 +04:00
|
|
|
{
|
2014-09-16 21:30:23 +04:00
|
|
|
aName.Truncate();
|
2002-04-26 08:50:21 +04:00
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
bool
|
2018-05-15 20:40:22 +03:00
|
|
|
HTMLSelectOptGroupAccessible::DoAction(uint8_t aIndex) const
|
2002-04-26 08:50:21 +04:00
|
|
|
{
|
2014-09-16 21:30:23 +04:00
|
|
|
return false;
|
2002-04-26 08:50:21 +04:00
|
|
|
}
|
|
|
|
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLComboboxAccessible
|
2009-12-10 22:12:19 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2001-11-07 03:12:16 +03:00
|
|
|
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::
|
|
|
|
HTMLComboboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
2012-05-29 05:18:45 +04:00
|
|
|
AccessibleWrap(aContent, aDoc)
|
2001-06-30 04:25:09 +04:00
|
|
|
{
|
2014-12-30 23:43:49 +03:00
|
|
|
mType = eHTMLComboboxType;
|
2012-12-18 09:22:26 +04:00
|
|
|
mGenericTypes |= eCombobox;
|
2016-04-01 04:40:56 +03:00
|
|
|
mStateFlags |= eNoKidsFromDOM;
|
2016-04-01 04:22:56 +03:00
|
|
|
|
|
|
|
nsIComboboxControlFrame* comboFrame = do_QueryFrame(GetFrame());
|
|
|
|
if (comboFrame) {
|
|
|
|
nsIFrame* listFrame = comboFrame->GetDropDown();
|
|
|
|
if (listFrame) {
|
|
|
|
mListAccessible = new HTMLComboboxListAccessible(mParent, mContent, mDoc);
|
|
|
|
Document()->BindToDocument(mListAccessible, nullptr);
|
|
|
|
AppendChild(mListAccessible);
|
|
|
|
}
|
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
|
|
|
|
2010-10-21 08:16:10 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLComboboxAccessible: Accessible
|
2010-10-21 08:16:10 +04:00
|
|
|
|
2012-01-12 07:07:35 +04:00
|
|
|
role
|
2018-05-07 22:05:50 +03:00
|
|
|
HTMLComboboxAccessible::NativeRole() const
|
2002-06-12 09:16:30 +04:00
|
|
|
{
|
2012-01-12 07:07:35 +04:00
|
|
|
return roles::COMBOBOX;
|
2002-06-12 09:16:30 +04:00
|
|
|
}
|
|
|
|
|
2015-02-19 07:37:32 +03:00
|
|
|
bool
|
|
|
|
HTMLComboboxAccessible::RemoveChild(Accessible* aChild)
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(aChild == mListAccessible);
|
|
|
|
if (AccessibleWrap::RemoveChild(aChild)) {
|
|
|
|
mListAccessible = nullptr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-06-12 08:04:35 +04:00
|
|
|
void
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::Shutdown()
|
2007-04-18 19:44:49 +04:00
|
|
|
{
|
2015-02-19 07:37:32 +03:00
|
|
|
MOZ_ASSERT(mDoc->IsDefunct() || !mListAccessible);
|
2016-04-01 03:46:58 +03:00
|
|
|
if (mListAccessible) {
|
|
|
|
mListAccessible->Shutdown();
|
|
|
|
mListAccessible = nullptr;
|
|
|
|
}
|
2007-04-18 19:44:49 +04:00
|
|
|
|
2015-02-19 07:37:32 +03:00
|
|
|
AccessibleWrap::Shutdown();
|
2007-04-18 19:44:49 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t
|
2018-05-15 21:04:50 +03:00
|
|
|
HTMLComboboxAccessible::NativeState() const
|
2002-06-12 09:16:30 +04:00
|
|
|
{
|
2012-06-06 14:27:46 +04:00
|
|
|
// As a HTMLComboboxAccessible we can have the following states:
|
2011-04-10 03:38:06 +04:00
|
|
|
// FOCUSED, FOCUSABLE, HASPOPUP, EXPANDED, COLLAPSED
|
2002-06-12 09:16:30 +04:00
|
|
|
// Get focus status from base class
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t state = Accessible::NativeState();
|
2002-06-12 09:16:30 +04:00
|
|
|
|
2012-05-07 17:42:56 +04:00
|
|
|
nsIComboboxControlFrame* comboFrame = do_QueryFrame(GetFrame());
|
2011-09-28 05:46:11 +04:00
|
|
|
if (comboFrame && comboFrame->IsDroppedDown())
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::EXPANDED;
|
2011-09-28 05:46:11 +04:00
|
|
|
else
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::COLLAPSED;
|
2002-06-12 09:16:30 +04:00
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
state |= states::HASPOPUP;
|
2011-04-10 03:38:06 +04:00
|
|
|
return state;
|
2002-06-12 09:16:30 +04:00
|
|
|
}
|
|
|
|
|
2011-04-23 17:14:05 +04:00
|
|
|
void
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::Description(nsString& aDescription)
|
2005-05-05 19:05:34 +04:00
|
|
|
{
|
|
|
|
aDescription.Truncate();
|
2007-01-11 23:07:36 +03:00
|
|
|
// First check to see if combo box itself has a description, perhaps through
|
2007-12-12 05:10:26 +03:00
|
|
|
// tooltip (title attribute) or via aria-describedby
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible::Description(aDescription);
|
2011-04-23 17:14:05 +04:00
|
|
|
if (!aDescription.IsEmpty())
|
|
|
|
return;
|
2011-09-28 05:46:11 +04:00
|
|
|
|
|
|
|
// Otherwise use description of selected option.
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* option = SelectedOption();
|
2011-04-23 17:14:05 +04:00
|
|
|
if (option)
|
|
|
|
option->Description(aDescription);
|
2005-05-05 19:05:34 +04:00
|
|
|
}
|
|
|
|
|
2012-04-09 13:48:41 +04:00
|
|
|
void
|
2018-05-15 19:55:28 +03:00
|
|
|
HTMLComboboxAccessible::Value(nsString& aValue) const
|
2001-11-07 03:12:16 +03:00
|
|
|
{
|
2011-09-28 05:46:11 +04:00
|
|
|
// Use accessible name of selected option.
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* option = SelectedOption();
|
2012-04-09 13:48:41 +04:00
|
|
|
if (option)
|
2012-05-01 07:08:31 +04:00
|
|
|
option->Name(aValue);
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint8_t
|
2018-05-15 20:40:22 +03:00
|
|
|
HTMLComboboxAccessible::ActionCount() const
|
2007-01-11 23:07:36 +03:00
|
|
|
{
|
2011-06-05 23:35:43 +04:00
|
|
|
return 1;
|
2007-01-11 23:07:36 +03:00
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
bool
|
2018-05-15 20:40:22 +03:00
|
|
|
HTMLComboboxAccessible::DoAction(uint8_t aIndex) const
|
2001-11-07 03:12:16 +03:00
|
|
|
{
|
2011-09-28 05:46:11 +04:00
|
|
|
if (aIndex != eAction_Click)
|
2014-09-16 21:30:23 +04:00
|
|
|
return false;
|
2007-01-11 23:07:36 +03:00
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
DoCommand();
|
2014-09-16 21:30:23 +04:00
|
|
|
return true;
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
void
|
|
|
|
HTMLComboboxAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName)
|
2007-01-11 23:07:36 +03:00
|
|
|
{
|
2014-09-16 21:30:23 +04:00
|
|
|
if (aIndex != HTMLComboboxAccessible::eAction_Click)
|
|
|
|
return;
|
|
|
|
|
2014-03-25 19:36:49 +04:00
|
|
|
nsIComboboxControlFrame* comboFrame = do_QueryFrame(GetFrame());
|
2014-09-16 21:30:23 +04:00
|
|
|
if (!comboFrame)
|
|
|
|
return;
|
|
|
|
|
2007-01-11 23:07:36 +03:00
|
|
|
if (comboFrame->IsDroppedDown())
|
2014-09-16 21:30:23 +04:00
|
|
|
aName.AssignLiteral("close");
|
2007-01-11 23:07:36 +03:00
|
|
|
else
|
2014-09-16 21:30:23 +04:00
|
|
|
aName.AssignLiteral("open");
|
2007-01-11 23:07:36 +03:00
|
|
|
}
|
|
|
|
|
2017-09-13 21:04:00 +03:00
|
|
|
bool
|
|
|
|
HTMLComboboxAccessible::IsAcceptableChild(nsIContent* aEl) const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLComboboxAccessible: Widgets
|
2011-09-28 05:46:11 +04:00
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::IsWidget() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::IsActiveWidget() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
return FocusMgr()->HasDOMFocus(mContent);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::AreItemsOperable() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
|
|
|
nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(GetFrame());
|
|
|
|
return comboboxFrame && comboboxFrame->IsDroppedDown();
|
|
|
|
}
|
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible*
|
2018-05-13 12:26:02 +03:00
|
|
|
HTMLComboboxAccessible::CurrentItem() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
return AreItemsOperable() ? mListAccessible->CurrentItem() : nullptr;
|
2011-09-28 05:46:11 +04:00
|
|
|
}
|
|
|
|
|
2011-12-08 16:20:15 +04:00
|
|
|
void
|
2018-05-13 13:14:55 +03:00
|
|
|
HTMLComboboxAccessible::SetCurrentItem(const Accessible* aItem)
|
2011-12-08 16:20:15 +04:00
|
|
|
{
|
|
|
|
if (AreItemsOperable())
|
|
|
|
mListAccessible->SetCurrentItem(aItem);
|
|
|
|
}
|
|
|
|
|
2011-09-28 05:46:11 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLComboboxAccessible: protected
|
2011-09-28 05:46:11 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible*
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxAccessible::SelectedOption() const
|
2011-09-28 05:46:11 +04:00
|
|
|
{
|
2018-03-22 00:39:04 +03:00
|
|
|
HTMLSelectElement* select = HTMLSelectElement::FromNode(mContent);
|
2016-07-01 05:59:38 +03:00
|
|
|
int32_t selectedIndex = select->SelectedIndex();
|
2011-09-28 05:46:11 +04:00
|
|
|
|
2016-07-01 05:59:38 +03:00
|
|
|
if (selectedIndex >= 0) {
|
|
|
|
HTMLOptionElement* option = select->Item(selectedIndex);
|
|
|
|
if (option) {
|
2012-05-27 13:01:40 +04:00
|
|
|
DocAccessible* document = Document();
|
2011-09-28 05:46:11 +04:00
|
|
|
if (document)
|
2016-07-01 05:59:38 +03:00
|
|
|
return document->GetAccessible(option);
|
2011-09-28 05:46:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2011-09-28 05:46:11 +04:00
|
|
|
}
|
|
|
|
|
2009-12-10 22:12:19 +03:00
|
|
|
|
2009-10-31 04:54:59 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLComboboxListAccessible
|
2009-10-31 04:54:59 +03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2003-02-27 04:51:13 +03:00
|
|
|
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxListAccessible::
|
2014-10-22 04:49:28 +04:00
|
|
|
HTMLComboboxListAccessible(Accessible* aParent, nsIContent* aContent,
|
2012-06-06 14:27:46 +04:00
|
|
|
DocAccessible* aDoc) :
|
|
|
|
HTMLSelectListAccessible(aContent, aDoc)
|
2001-06-30 04:25:09 +04:00
|
|
|
{
|
2012-12-11 07:31:42 +04:00
|
|
|
mStateFlags |= eSharedNode;
|
2007-01-11 23:07:36 +03:00
|
|
|
}
|
|
|
|
|
2010-10-21 08:16:10 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2013-10-29 07:30:55 +04:00
|
|
|
// HTMLComboboxAccessible: Accessible
|
2010-10-21 08:16:10 +04:00
|
|
|
|
2008-11-01 06:58:07 +03:00
|
|
|
nsIFrame*
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxListAccessible::GetFrame() const
|
2007-01-11 23:07:36 +03:00
|
|
|
{
|
2012-06-06 14:27:46 +04:00
|
|
|
nsIFrame* frame = HTMLSelectListAccessible::GetFrame();
|
2014-03-25 19:36:49 +04:00
|
|
|
nsIComboboxControlFrame* comboBox = do_QueryFrame(frame);
|
|
|
|
if (comboBox) {
|
|
|
|
return comboBox->GetDropDown();
|
2007-04-17 01:11:29 +04:00
|
|
|
}
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
return nullptr;
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
2003-02-27 04:51:13 +03:00
|
|
|
|
2012-05-16 06:38:49 +04:00
|
|
|
role
|
2018-05-07 22:05:50 +03:00
|
|
|
HTMLComboboxListAccessible::NativeRole() const
|
2012-05-16 06:38:49 +04:00
|
|
|
{
|
|
|
|
return roles::COMBOBOX_LIST;
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t
|
2018-05-15 21:04:50 +03:00
|
|
|
HTMLComboboxListAccessible::NativeState() const
|
2003-02-27 04:51:13 +03:00
|
|
|
{
|
2012-06-06 14:27:46 +04:00
|
|
|
// As a HTMLComboboxListAccessible we can have the following states:
|
2011-04-10 03:38:06 +04:00
|
|
|
// FOCUSED, FOCUSABLE, FLOATING, INVISIBLE
|
2003-02-27 04:51:13 +03:00
|
|
|
// Get focus status from base class
|
2012-08-22 19:56:38 +04:00
|
|
|
uint64_t state = Accessible::NativeState();
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2012-05-07 17:42:56 +04:00
|
|
|
nsIComboboxControlFrame* comboFrame = do_QueryFrame(mParent->GetFrame());
|
2007-05-07 07:12:00 +04:00
|
|
|
if (comboFrame && comboFrame->IsDroppedDown())
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::FLOATING;
|
2003-04-15 12:45:55 +04:00
|
|
|
else
|
2011-04-10 03:38:06 +04:00
|
|
|
state |= states::INVISIBLE;
|
2007-03-15 17:18:33 +03:00
|
|
|
|
2011-04-10 03:38:06 +04:00
|
|
|
return state;
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
2001-06-30 04:25:09 +04:00
|
|
|
|
2014-09-16 21:30:23 +04:00
|
|
|
nsRect
|
|
|
|
HTMLComboboxListAccessible::RelativeBounds(nsIFrame** aBoundingFrame) const
|
2001-06-30 04:25:09 +04:00
|
|
|
{
|
2012-07-30 18:20:58 +04:00
|
|
|
*aBoundingFrame = nullptr;
|
2007-05-07 07:12:00 +04:00
|
|
|
|
2012-05-29 05:18:45 +04:00
|
|
|
Accessible* comboAcc = Parent();
|
2010-01-11 17:14:06 +03:00
|
|
|
if (!comboAcc)
|
2014-09-16 21:30:23 +04:00
|
|
|
return nsRect();
|
2009-12-10 22:12:19 +03:00
|
|
|
|
2011-04-10 03:38:06 +04:00
|
|
|
if (0 == (comboAcc->State() & states::COLLAPSED)) {
|
2014-09-16 21:30:23 +04:00
|
|
|
return HTMLSelectListAccessible::RelativeBounds(aBoundingFrame);
|
2007-05-07 07:12:00 +04:00
|
|
|
}
|
2003-02-27 04:51:13 +03:00
|
|
|
|
2010-06-11 12:23:18 +04:00
|
|
|
// Get the first option.
|
2011-12-07 11:20:17 +04:00
|
|
|
nsIContent* content = mContent->GetFirstChild();
|
2014-09-16 21:30:23 +04:00
|
|
|
if (!content)
|
|
|
|
return nsRect();
|
|
|
|
|
2009-12-25 00:20:05 +03:00
|
|
|
nsIFrame* frame = content->GetPrimaryFrame();
|
2003-02-27 04:51:13 +03:00
|
|
|
if (!frame) {
|
2012-07-30 18:20:58 +04:00
|
|
|
*aBoundingFrame = nullptr;
|
2014-09-16 21:30:23 +04:00
|
|
|
return nsRect();
|
2003-02-27 04:51:13 +03:00
|
|
|
}
|
|
|
|
|
2003-09-23 21:05:29 +04:00
|
|
|
*aBoundingFrame = frame->GetParent();
|
2014-09-16 21:30:23 +04:00
|
|
|
return (*aBoundingFrame)->GetRect();
|
2001-06-30 04:25:09 +04:00
|
|
|
}
|
2011-11-01 04:52:27 +04:00
|
|
|
|
2017-09-13 21:04:00 +03:00
|
|
|
bool
|
|
|
|
HTMLComboboxListAccessible::IsAcceptableChild(nsIContent* aEl) const
|
|
|
|
{
|
|
|
|
return aEl->IsAnyOfHTMLElements(nsGkAtoms::option, nsGkAtoms::optgroup);
|
|
|
|
}
|
|
|
|
|
2011-11-01 04:52:27 +04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2012-06-06 14:27:46 +04:00
|
|
|
// HTMLComboboxListAccessible: Widgets
|
2011-11-01 04:52:27 +04:00
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxListAccessible::IsActiveWidget() const
|
2011-11-01 04:52:27 +04:00
|
|
|
{
|
|
|
|
return mParent && mParent->IsActiveWidget();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-06-06 14:27:46 +04:00
|
|
|
HTMLComboboxListAccessible::AreItemsOperable() const
|
2011-11-01 04:52:27 +04:00
|
|
|
{
|
|
|
|
return mParent && mParent->AreItemsOperable();
|
|
|
|
}
|