Bug 590176 - add pseudo SelectAccessible interface, r=marcoz, davidb, a=davidb

This commit is contained in:
Alexander Surkov 2010-09-02 09:46:59 +09:00
parent 9320bf1acd
commit 82229f170c
24 changed files with 1349 additions and 904 deletions

View File

@ -475,10 +475,7 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
}
//nsIAccessibleSelection
nsCOMPtr<nsIAccessibleSelectable> accessInterfaceSelection;
QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accessInterfaceSelection));
if (accessInterfaceSelection) {
if (IsSelect()) {
interfacesBits |= 1 << MAI_INTERFACE_SELECTION;
}
}

View File

@ -60,51 +60,34 @@ gboolean
addSelectionCB(AtkSelection *aSelection, gint i)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return FALSE;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, FALSE);
return NS_SUCCEEDED(accSelection->AddChildToSelection(i));
return accWrap->AddItemToSelection(i);
}
gboolean
clearSelectionCB(AtkSelection *aSelection)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return FALSE;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, FALSE);
return NS_SUCCEEDED(accSelection->ClearSelection());
return accWrap->UnselectAll();
}
AtkObject *
refSelectionCB(AtkSelection *aSelection, gint i)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return nsnull;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, nsnull);
nsCOMPtr<nsIAccessible> accSelect;
accSelection->RefSelection(i, getter_AddRefs(accSelect));
if (!accSelect) {
nsAccessible* selectedItem = accWrap->GetSelectedItem(i);
if (!selectedItem)
return nsnull;
}
AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accSelect);
AtkObject* atkObj = nsAccessibleWrap::GetAtkObject(selectedItem);
if (atkObj) {
g_object_ref(atkObj);
}
@ -115,65 +98,38 @@ gint
getSelectionCountCB(AtkSelection *aSelection)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return -1;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, -1);
PRInt32 num = 0;
nsresult rv = accSelection->GetSelectionCount(&num);
return (NS_FAILED(rv)) ? -1 : num;
return accWrap->SelectedItemCount();
}
gboolean
isChildSelectedCB(AtkSelection *aSelection, gint i)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return FALSE;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, FALSE);
PRBool result = FALSE;
nsresult rv = accSelection->IsChildSelected(i, &result);
return (NS_FAILED(rv)) ? FALSE : result;
return accWrap->IsItemSelected(i);
}
gboolean
removeSelectionCB(AtkSelection *aSelection, gint i)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return FALSE;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, FALSE);
nsresult rv = accSelection->RemoveChildFromSelection(i);
return (NS_FAILED(rv)) ? FALSE : TRUE;
return accWrap->RemoveItemFromSelection(i);
}
gboolean
selectAllSelectionCB(AtkSelection *aSelection)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aSelection));
if (!accWrap)
if (!accWrap || !accWrap->IsSelect())
return FALSE;
nsCOMPtr<nsIAccessibleSelectable> accSelection;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleSelectable),
getter_AddRefs(accSelection));
NS_ENSURE_TRUE(accSelection, FALSE);
PRBool result = FALSE;
nsresult rv = accSelection->SelectAllSelection(&result);
return (NS_FAILED(rv)) ? FALSE : result;
return accWrap->SelectAll();
}

View File

@ -42,7 +42,6 @@
#define __MAI_INTERFACE_SELECTION_H__
#include "nsMai.h"
#include "nsIAccessibleSelectable.h"
G_BEGIN_DECLS

View File

@ -376,16 +376,11 @@ nsAccUtils::GetSelectableContainer(nsAccessible *aAccessible, PRUint32 aState)
if (!(aState & nsIAccessibleStates::STATE_SELECTABLE))
return nsnull;
nsCOMPtr<nsIAccessibleSelectable> container;
nsAccessible *parent = aAccessible;
while (!container) {
parent = parent->GetParent();
if (!parent || Role(parent) == nsIAccessibleRole::ROLE_PANE)
nsAccessible* parent = aAccessible;
while ((parent = parent->GetParent()) && !parent->IsSelect()) {
if (Role(parent) == nsIAccessibleRole::ROLE_PANE)
return nsnull;
container = do_QueryObject(parent);
}
return parent;
}

View File

@ -155,20 +155,12 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
}
if (aIID.Equals(NS_GET_IID(nsIAccessibleSelectable))) {
if (mRoleMapEntry &&
(mRoleMapEntry->attributeMap1 == eARIAMultiSelectable ||
mRoleMapEntry->attributeMap2 == eARIAMultiSelectable ||
mRoleMapEntry->attributeMap3 == eARIAMultiSelectable)) {
// If we have an ARIA role attribute present and the role allows multi
// selectable state, then we need to support nsIAccessibleSelectable.
// If either attribute (role or multiselectable) change, then we'll
// destroy this accessible so that we can follow COM identity rules.
if (IsSelect()) {
*aInstancePtr = static_cast<nsIAccessibleSelectable*>(this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
if (aIID.Equals(NS_GET_IID(nsIAccessibleValue))) {
@ -2381,22 +2373,18 @@ nsAccessible::DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex)
// nsIAccessibleSelectable
NS_IMETHODIMP nsAccessible::GetSelectedChildren(nsIArray **aSelectedAccessibles)
{
NS_ENSURE_ARG_POINTER(aSelectedAccessibles);
*aSelectedAccessibles = nsnull;
nsCOMPtr<nsIMutableArray> selectedAccessibles =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_STATE(selectedAccessibles);
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsIAccessible *selected = nsnull;
while ((selected = iter.GetNext()))
selectedAccessibles->AppendElement(selected, PR_FALSE);
PRUint32 length = 0;
selectedAccessibles->GetLength(&length);
if (length) { // length of nsIArray containing selected options
*aSelectedAccessibles = selectedAccessibles;
NS_ADDREF(*aSelectedAccessibles);
nsCOMPtr<nsIArray> items = SelectedItems();
if (items) {
PRUint32 length = 0;
items->GetLength(&length);
if (length)
items.swap(*aSelectedAccessibles);
}
return NS_OK;
@ -2408,23 +2396,20 @@ NS_IMETHODIMP nsAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **aSelect
NS_ENSURE_ARG_POINTER(aSelected);
*aSelected = nsnull;
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsAccessible *selected = nsnull;
PRInt32 count = 0;
while (count ++ <= aIndex) {
selected = iter.GetNext();
if (!selected) {
// The index is out of range.
return NS_ERROR_INVALID_ARG;
}
*aSelected = GetSelectedItem(aIndex);
if (*aSelected) {
NS_ADDREF(*aSelected);
return NS_OK;
}
NS_IF_ADDREF(*aSelected = selected);
return NS_OK;
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
@ -2432,83 +2417,65 @@ NS_IMETHODIMP nsAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
NS_ENSURE_ARG_POINTER(aSelectionCount);
*aSelectionCount = 0;
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsAccessible *selected = nsnull;
while ((selected = iter.GetNext()))
++(*aSelectionCount);
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
*aSelectionCount = SelectedItemCount();
return NS_OK;
}
NS_IMETHODIMP nsAccessible::AddChildToSelection(PRInt32 aIndex)
{
// Tree views and other container widgets which may have grandchildren should
// implement a selection methods for their specific interfaces, because being
// able to deal with selection on a per-child basis would not be enough.
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
nsAccessible* child = GetChildAt(aIndex);
PRUint32 state = nsAccUtils::State(child);
if (!(state & nsIAccessibleStates::STATE_SELECTABLE)) {
return NS_OK;
}
return child->SetSelected(PR_TRUE);
return aIndex >= 0 && AddItemToSelection(aIndex) ?
NS_OK : NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsAccessible::RemoveChildFromSelection(PRInt32 aIndex)
{
// Tree views and other container widgets which may have grandchildren should
// implement a selection methods for their specific interfaces, because being
// able to deal with selection on a per-child basis would not be enough.
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
nsAccessible* child = GetChildAt(aIndex);
PRUint32 state = nsAccUtils::State(child);
if (!(state & nsIAccessibleStates::STATE_SELECTED)) {
return NS_OK;
}
return child->SetSelected(PR_FALSE);
return aIndex >=0 && RemoveItemFromSelection(aIndex) ?
NS_OK : NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsAccessible::IsChildSelected(PRInt32 aIndex, PRBool *aIsSelected)
{
// Tree views and other container widgets which may have grandchildren should
// implement a selection methods for their specific interfaces, because being
// able to deal with selection on a per-child basis would not be enough.
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = PR_FALSE;
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
nsAccessible* child = GetChildAt(aIndex);
PRUint32 state = nsAccUtils::State(child);
if (state & nsIAccessibleStates::STATE_SELECTED) {
*aIsSelected = PR_TRUE;
}
*aIsSelected = IsItemSelected(aIndex);
return NS_OK;
}
NS_IMETHODIMP
nsAccessible::ClearSelection()
{
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsAccessible *selected = nsnull;
while ((selected = iter.GetNext()))
selected->SetSelected(PR_FALSE);
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
UnselectAll();
return NS_OK;
}
NS_IMETHODIMP nsAccessible::SelectAllSelection(PRBool *_retval)
NS_IMETHODIMP
nsAccessible::SelectAllSelection(PRBool* aIsMultiSelect)
{
AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
nsAccessible *selectable = nsnull;
while((selectable = iter.GetNext()))
selectable->SetSelected(PR_TRUE);
NS_ENSURE_ARG_POINTER(aIsMultiSelect);
*aIsMultiSelect = PR_FALSE;
if (IsDefunct() || !IsSelect())
return NS_ERROR_FAILURE;
*aIsMultiSelect = SelectAll();
return NS_OK;
}
@ -3033,6 +3000,138 @@ nsAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
// SelectAccessible
bool
nsAccessible::IsSelect()
{
// If we have an ARIA role attribute present and the role allows multi
// selectable state, then we need to support SelectAccessible interface. If
// either attribute (role or multiselectable) change, then we'll destroy this
// accessible so that we can follow COM identity rules.
return mRoleMapEntry &&
(mRoleMapEntry->attributeMap1 == eARIAMultiSelectable ||
mRoleMapEntry->attributeMap2 == eARIAMultiSelectable ||
mRoleMapEntry->attributeMap3 == eARIAMultiSelectable);
}
already_AddRefed<nsIArray>
nsAccessible::SelectedItems()
{
nsCOMPtr<nsIMutableArray> selectedItems = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (!selectedItems)
return nsnull;
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsIAccessible* selected = nsnull;
while ((selected = iter.GetNext()))
selectedItems->AppendElement(selected, PR_FALSE);
nsIMutableArray* items = nsnull;
selectedItems.forget(&items);
return items;
}
PRUint32
nsAccessible::SelectedItemCount()
{
PRUint32 count = 0;
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsAccessible* selected = nsnull;
while ((selected = iter.GetNext()))
++count;
return count;
}
nsAccessible*
nsAccessible::GetSelectedItem(PRUint32 aIndex)
{
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
nsAccessible* selected = nsnull;
PRUint32 index = 0;
while ((selected = iter.GetNext()) && index < aIndex)
index++;
return selected;
}
bool
nsAccessible::IsItemSelected(PRUint32 aIndex)
{
PRUint32 index = 0;
AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
nsAccessible* selected = nsnull;
while ((selected = iter.GetNext()) && index < aIndex)
index++;
return selected &&
nsAccUtils::State(selected) & nsIAccessibleStates::STATE_SELECTED;
}
bool
nsAccessible::AddItemToSelection(PRUint32 aIndex)
{
PRUint32 index = 0;
AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
nsAccessible* selected = nsnull;
while ((selected = iter.GetNext()) && index < aIndex)
index++;
if (selected)
selected->SetSelected(PR_TRUE);
return static_cast<bool>(selected);
}
bool
nsAccessible::RemoveItemFromSelection(PRUint32 aIndex)
{
PRUint32 index = 0;
AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
nsAccessible* selected = nsnull;
while ((selected = iter.GetNext()) && index < aIndex)
index++;
if (selected)
selected->SetSelected(PR_FALSE);
return static_cast<bool>(selected);
}
bool
nsAccessible::SelectAll()
{
bool success = false;
nsAccessible* selectable = nsnull;
AccIterator iter(this, filters::GetSelectable, AccIterator::eTreeNav);
while((selectable = iter.GetNext())) {
success = true;
selectable->SetSelected(PR_TRUE);
}
return success;
}
bool
nsAccessible::UnselectAll()
{
bool success = false;
nsAccessible* selected = nsnull;
AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
while ((selected = iter.GetNext())) {
success = true;
selected->SetSelected(PR_FALSE);
}
return success;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccessible protected methods

View File

@ -370,6 +370,55 @@ public:
*/
virtual already_AddRefed<nsIURI> GetAnchorURI(PRUint32 aAnchorIndex);
//////////////////////////////////////////////////////////////////////////////
// SelectAccessible
/**
* Return true if the accessible is a select control containing selectable
* items.
*/
virtual bool IsSelect();
/**
* Return an array of selected items.
*/
virtual already_AddRefed<nsIArray> SelectedItems();
/**
* Return the number of selected items.
*/
virtual PRUint32 SelectedItemCount();
/**
* Return selected item at the given index.
*/
virtual nsAccessible* GetSelectedItem(PRUint32 aIndex);
/**
* Determine if item at the given index is selected.
*/
virtual bool IsItemSelected(PRUint32 aIndex);
/**
* Add item at the given index the selection. Return true if success.
*/
virtual bool AddItemToSelection(PRUint32 aIndex);
/**
* Remove item at the given index from the selection. Return if success.
*/
virtual bool RemoveItemFromSelection(PRUint32 aIndex);
/**
* Select all items. Return true if success.
*/
virtual bool SelectAll();
/**
* Unselect all items. Return true if success.
*/
virtual bool UnselectAll();
protected:
//////////////////////////////////////////////////////////////////////////////

View File

@ -1174,7 +1174,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
if (aAttribute == nsAccessibilityAtoms::aria_multiselectable &&
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
// This affects whether the accessible supports nsIAccessibleSelectable.
// This affects whether the accessible supports SelectAccessible.
// COM says we cannot change what interfaces are supported on-the-fly,
// so invalidate this object. A new one will be created on demand.
InvalidateCacheSubtree(aContent,

View File

@ -56,252 +56,13 @@
#include "nsIServiceManager.h"
#include "nsIMutableArray.h"
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectableAccessible
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectableAccessible::iterator
nsHTMLSelectableAccessible::iterator::iterator(nsHTMLSelectableAccessible *aParent, nsIWeakReference *aWeakShell):
mWeakShell(aWeakShell), mParentSelect(aParent)
{
mLength = mIndex = 0;
mSelCount = 0;
nsCOMPtr<nsIDOMHTMLSelectElement> htmlSelect =
do_QueryInterface(mParentSelect->mContent);
if (htmlSelect) {
htmlSelect->GetOptions(getter_AddRefs(mOptions));
if (mOptions)
mOptions->GetLength(&mLength);
}
}
PRBool nsHTMLSelectableAccessible::iterator::Advance()
{
if (mIndex < mLength) {
nsCOMPtr<nsIDOMNode> tempNode;
if (mOptions) {
mOptions->Item(mIndex, getter_AddRefs(tempNode));
mOption = do_QueryInterface(tempNode);
}
mIndex++;
return PR_TRUE;
}
return PR_FALSE;
}
void nsHTMLSelectableAccessible::iterator::CalcSelectionCount(PRInt32 *aSelectionCount)
{
PRBool isSelected = PR_FALSE;
if (mOption)
mOption->GetSelected(&isSelected);
if (isSelected)
(*aSelectionCount)++;
}
void
nsHTMLSelectableAccessible::iterator::AddAccessibleIfSelected(nsIMutableArray *aSelectedAccessibles,
nsPresContext *aContext)
{
PRBool isSelected = PR_FALSE;
nsAccessible *optionAcc = nsnull;
if (mOption) {
mOption->GetSelected(&isSelected);
if (isSelected) {
nsCOMPtr<nsIContent> optionContent(do_QueryInterface(mOption));
optionAcc = GetAccService()->GetAccessibleInWeakShell(optionContent,
mWeakShell);
}
}
if (optionAcc)
aSelectedAccessibles->AppendElement(static_cast<nsIAccessible*>(optionAcc),
PR_FALSE);
}
PRBool
nsHTMLSelectableAccessible::iterator::GetAccessibleIfSelected(PRInt32 aIndex,
nsPresContext *aContext,
nsIAccessible **aAccessible)
{
PRBool isSelected = PR_FALSE;
*aAccessible = nsnull;
if (mOption) {
mOption->GetSelected(&isSelected);
if (isSelected) {
if (mSelCount == aIndex) {
nsCOMPtr<nsIContent> optionContent(do_QueryInterface(mOption));
nsAccessible *accessible =
GetAccService()->GetAccessibleInWeakShell(optionContent, mWeakShell);
NS_IF_ADDREF(*aAccessible = accessible);
return PR_TRUE;
}
mSelCount++;
}
}
return PR_FALSE;
}
void nsHTMLSelectableAccessible::iterator::Select(PRBool aSelect)
{
if (mOption)
mOption->SetSelected(aSelect);
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectableAccessible
nsHTMLSelectableAccessible::
nsHTMLSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
nsAccessibleWrap(aContent, aShell)
{
}
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLSelectableAccessible, nsAccessible, nsIAccessibleSelectable)
// Helper methods
NS_IMETHODIMP nsHTMLSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
{
*aSelState = PR_FALSE;
nsCOMPtr<nsIDOMHTMLSelectElement> htmlSelect(do_QueryInterface(mContent));
if (!htmlSelect)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMHTMLOptionsCollection> options;
htmlSelect->GetOptions(getter_AddRefs(options));
if (!options)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMNode> tempNode;
options->Item(aIndex, getter_AddRefs(tempNode));
nsCOMPtr<nsIDOMHTMLOptionElement> tempOption(do_QueryInterface(tempNode));
if (!tempOption)
return NS_ERROR_FAILURE;
tempOption->GetSelected(aSelState);
nsresult rv = NS_OK;
if (eSelection_Add == aMethod && !(*aSelState))
rv = tempOption->SetSelected(PR_TRUE);
else if (eSelection_Remove == aMethod && (*aSelState))
rv = tempOption->SetSelected(PR_FALSE);
return rv;
}
// Interface methods
NS_IMETHODIMP nsHTMLSelectableAccessible::GetSelectedChildren(nsIArray **_retval)
{
*_retval = nsnull;
nsCOMPtr<nsIMutableArray> selectedAccessibles =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_STATE(selectedAccessibles);
nsPresContext *context = GetPresContext();
if (!context)
return NS_ERROR_FAILURE;
nsHTMLSelectableAccessible::iterator iter(this, mWeakShell);
while (iter.Advance())
iter.AddAccessibleIfSelected(selectedAccessibles, context);
PRUint32 uLength = 0;
selectedAccessibles->GetLength(&uLength);
if (uLength != 0) { // length of nsIArray containing selected options
*_retval = selectedAccessibles;
NS_ADDREF(*_retval);
}
return NS_OK;
}
// return the nth selected child's nsIAccessible object
NS_IMETHODIMP nsHTMLSelectableAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **_retval)
{
*_retval = nsnull;
nsPresContext *context = GetPresContext();
if (!context)
return NS_ERROR_FAILURE;
nsHTMLSelectableAccessible::iterator iter(this, mWeakShell);
while (iter.Advance())
if (iter.GetAccessibleIfSelected(aIndex, context, _retval))
return NS_OK;
// No matched item found
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsHTMLSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
{
*aSelectionCount = 0;
nsHTMLSelectableAccessible::iterator iter(this, mWeakShell);
while (iter.Advance())
iter.CalcSelectionCount(aSelectionCount);
return NS_OK;
}
NS_IMETHODIMP nsHTMLSelectableAccessible::AddChildToSelection(PRInt32 aIndex)
{
PRBool isSelected;
return ChangeSelection(aIndex, eSelection_Add, &isSelected);
}
NS_IMETHODIMP nsHTMLSelectableAccessible::RemoveChildFromSelection(PRInt32 aIndex)
{
PRBool isSelected;
return ChangeSelection(aIndex, eSelection_Remove, &isSelected);
}
NS_IMETHODIMP nsHTMLSelectableAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval)
{
*_retval = PR_FALSE;
return ChangeSelection(aIndex, eSelection_GetState, _retval);
}
NS_IMETHODIMP nsHTMLSelectableAccessible::ClearSelection()
{
nsHTMLSelectableAccessible::iterator iter(this, mWeakShell);
while (iter.Advance())
iter.Select(PR_FALSE);
return NS_OK;
}
NS_IMETHODIMP nsHTMLSelectableAccessible::SelectAllSelection(PRBool *_retval)
{
*_retval = PR_FALSE;
nsCOMPtr<nsIDOMHTMLSelectElement> htmlSelect(do_QueryInterface(mContent));
if (!htmlSelect)
return NS_ERROR_FAILURE;
htmlSelect->GetMultiple(_retval);
if (*_retval) {
nsHTMLSelectableAccessible::iterator iter(this, mWeakShell);
while (iter.Advance())
iter.Select(PR_TRUE);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectListAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTMLSelectListAccessible::
nsHTMLSelectListAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
nsHTMLSelectableAccessible(aContent, aShell)
nsAccessibleWrap(aContent, aShell)
{
}
@ -312,8 +73,7 @@ nsresult
nsHTMLSelectListAccessible::GetStateInternal(PRUint32 *aState,
PRUint32 *aExtraState)
{
nsresult rv = nsHTMLSelectableAccessible::GetStateInternal(aState,
aExtraState);
nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState);
NS_ENSURE_A11Y_SUCCESS(rv, rv);
// As a nsHTMLSelectListAccessible we can have the following states:
@ -352,6 +112,33 @@ nsHTMLSelectListAccessible::GetRoleInternal(PRUint32 *aRole)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectListAccessible: SelectAccessible
bool
nsHTMLSelectListAccessible::IsSelect()
{
return true;
}
bool
nsHTMLSelectListAccessible::SelectAll()
{
nsCOMPtr<nsIDOMHTMLSelectElement> selectElm(do_QueryInterface(mContent));
PRBool isMultiple = PR_FALSE;
selectElm->GetMultiple(&isMultiple);
return isMultiple ? nsAccessibleWrap::SelectAll() : false;
}
bool
nsHTMLSelectListAccessible::UnselectAll()
{
nsCOMPtr<nsIDOMHTMLSelectElement> selectElm(do_QueryInterface(mContent));
PRBool isMultiple = PR_FALSE;
selectElm->GetMultiple(&isMultiple);
return isMultiple ? nsAccessibleWrap::UnselectAll() : false;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectListAccessible: nsAccessible protected
@ -676,6 +463,16 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
nsHTMLSelectOptionAccessible::SetSelected(PRBool aSelect)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMHTMLOptionElement> optionElm(do_QueryInterface(mContent));
return optionElm->SetSelected(aSelect);
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLSelectOptionAccessible: static methods

View File

@ -39,7 +39,6 @@
#ifndef __nsHTMLSelectAccessible_h__
#define __nsHTMLSelectAccessible_h__
#include "nsIAccessibleSelectable.h"
#include "nsAccessibilityAtoms.h"
#include "nsHTMLFormControlAccessible.h"
#include "nsIDOMHTMLOptionsCollection.h"
@ -63,58 +62,10 @@ class nsIMutableArray;
* - nsHTMLSelectOptionAccessible(s)
*/
/** ------------------------------------------------------ */
/** First, the common widgets */
/** ------------------------------------------------------ */
/*
* The HTML implementation of nsIAccessibleSelectable.
*/
class nsHTMLSelectableAccessible : public nsAccessibleWrap
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLESELECTABLE
nsHTMLSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell);
virtual ~nsHTMLSelectableAccessible() {}
protected:
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
class iterator
{
protected:
PRUint32 mLength;
PRUint32 mIndex;
PRInt32 mSelCount;
nsCOMPtr<nsIDOMHTMLOptionsCollection> mOptions;
nsCOMPtr<nsIDOMHTMLOptionElement> mOption;
nsCOMPtr<nsIWeakReference> mWeakShell;
nsHTMLSelectableAccessible *mParentSelect;
public:
iterator(nsHTMLSelectableAccessible *aParent, nsIWeakReference *aWeakShell);
void CalcSelectionCount(PRInt32 *aSelectionCount);
void Select(PRBool aSelect);
void AddAccessibleIfSelected(nsIMutableArray *aSelectedAccessibles,
nsPresContext *aContext);
PRBool GetAccessibleIfSelected(PRInt32 aIndex, nsPresContext *aContext,
nsIAccessible **aAccessible);
PRBool Advance();
};
friend class iterator;
};
/*
* The list that contains all the options in the select.
*/
class nsHTMLSelectListAccessible : public nsHTMLSelectableAccessible
class nsHTMLSelectListAccessible : public nsAccessibleWrap
{
public:
@ -125,6 +76,11 @@ public:
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// SelectAccessible
virtual bool IsSelect();
virtual bool SelectAll();
virtual bool UnselectAll();
protected:
// nsAccessible
@ -153,6 +109,7 @@ public:
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD SetSelected(PRBool aSelect);
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);

View File

@ -44,7 +44,6 @@
#include "nsRelUtils.h"
#include "nsIAccessibleDocument.h"
#include "nsIAccessibleSelectable.h"
#include "nsIAccessibleEvent.h"
#include "nsIAccessibleWin32Object.h"
@ -697,7 +696,7 @@ __try {
/**
* This method is called when a client wants to know which children of a node
* are selected. Note that this method can only find selected children for
* nsIAccessible object which implement nsIAccessibleSelectable.
* nsIAccessible object which implement SelectAccessible.
*
* The VARIANT return value arguement is expected to either contain a single IAccessible
* or an IEnumVARIANT of IAccessibles. We return the IEnumVARIANT regardless of the number
@ -717,17 +716,12 @@ __try {
VariantInit(pvarChildren);
pvarChildren->vt = VT_EMPTY;
nsCOMPtr<nsIAccessibleSelectable>
select(do_QueryInterface(static_cast<nsIAccessible*>(this)));
if (select) { // do we have an nsIAccessibleSelectable?
// we have an accessible that can have children selected
nsCOMPtr<nsIArray> selectedOptions;
// gets the selected options as nsIAccessibles.
select->GetSelectedChildren(getter_AddRefs(selectedOptions));
if (selectedOptions) { // false if the select has no children or none are selected
if (IsSelect()) {
nsCOMPtr<nsIArray> selectedItems = SelectedItems();
if (selectedItems) {
// 1) Create and initialize the enumeration
nsRefPtr<AccessibleEnumerator> pEnum = new AccessibleEnumerator(selectedOptions);
nsRefPtr<AccessibleEnumerator> pEnum =
new AccessibleEnumerator(selectedItems);
// 2) Put the enumerator in the VARIANT
if (!pEnum)

View File

@ -316,12 +316,9 @@ nsXFormsEditableAccessible::GetAssociatedEditor(nsIEditor **aEditor)
return sXFormsService->GetEditor(DOMNode, aEditor);
}
////////////////////////////////////////////////////////////////////////////////
// nsXFormsSelectableAccessible
NS_IMPL_ISUPPORTS_INHERITED1(nsXFormsSelectableAccessible,
nsXFormsEditableAccessible,
nsIAccessibleSelectable)
////////////////////////////////////////////////////////////////////////////////
nsXFormsSelectableAccessible::
nsXFormsSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
@ -331,265 +328,225 @@ nsXFormsSelectableAccessible::
mContent->NodeInfo()->Equals(nsAccessibilityAtoms::select1);
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::GetSelectedChildren(nsIArray **aAccessibles)
bool
nsXFormsSelectableAccessible::IsSelect()
{
NS_ENSURE_ARG_POINTER(aAccessibles);
return true;
}
*aAccessibles = nsnull;
nsCOMPtr<nsIMutableArray> accessibles =
already_AddRefed<nsIArray>
nsXFormsSelectableAccessible::SelectedItems()
{
nsCOMPtr<nsIMutableArray> selectedItems =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_TRUE(accessibles, NS_ERROR_OUT_OF_MEMORY);
if (!selectedItems)
return nsnull;
nsresult rv;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element) {
nsCOMPtr<nsIDOMNode> item;
nsCOMPtr<nsIDOMNode> itemDOMNode;
rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(item));
NS_ENSURE_SUCCESS(rv, rv);
if (!item)
return NS_OK;
nsCOMPtr<nsIAccessible> accessible;
GetAccService()->GetAccessibleFor(item, getter_AddRefs(accessible));
NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
accessibles->AppendElement(accessible, PR_FALSE);
NS_ADDREF(*aAccessibles = accessibles);
return NS_OK;
}
nsCOMPtr<nsIDOMNodeList> items;
rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
getter_AddRefs(items));
NS_ENSURE_SUCCESS(rv, rv);
if (!items)
return NS_OK;
PRUint32 length = 0;
items->GetLength(&length);
if (!length)
return NS_OK;
for (PRUint32 index = 0; index < length; index++) {
nsCOMPtr<nsIDOMNode> item;
items->Item(index, getter_AddRefs(item));
NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessible> accessible;
GetAccService()->GetAccessibleFor(item, getter_AddRefs(accessible));
NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
accessibles->AppendElement(accessible, PR_FALSE);
}
NS_ADDREF(*aAccessibles = accessibles);
return NS_OK;
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::GetSelectionCount(PRInt32 *aCount)
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
nsresult rv;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element) {
nsCOMPtr<nsIDOMNode> item;
rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(item));
NS_ENSURE_SUCCESS(rv, rv);
getter_AddRefs(itemDOMNode));
if (NS_FAILED(rv) || !itemDOMNode)
return nsnull;
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
nsIAccessible* item = GetAccService()->GetAccessibleInWeakShell(itemNode,
mWeakShell);
if (item)
*aCount = 1;
selectedItems->AppendElement(item, PR_FALSE);
return NS_OK;
nsIMutableArray* items = nsnull;
selectedItems.forget(&items);
return items;
}
nsCOMPtr<nsIDOMNodeList> items;
nsCOMPtr<nsIDOMNodeList> itemNodeList;
rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
getter_AddRefs(items));
NS_ENSURE_SUCCESS(rv, rv);
if (!items)
return NS_OK;
getter_AddRefs(itemNodeList));
if (NS_FAILED(rv) || !itemNodeList)
return nsnull;
PRUint32 length = 0;
items->GetLength(&length);
if (length)
*aCount = length;
itemNodeList->GetLength(&length);
for (PRUint32 index = 0; index < length; index++) {
nsCOMPtr<nsIDOMNode> itemDOMNode;
itemNodeList->Item(index, getter_AddRefs(itemDOMNode));
if (!itemDOMNode)
return nsnull;
return NS_OK;
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
nsIAccessible* item = GetAccService()->GetAccessibleInWeakShell(itemNode,
mWeakShell);
if (item)
selectedItems->AppendElement(item, PR_FALSE);
}
nsIMutableArray* items = nsnull;
selectedItems.forget(&items);
return items;
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::AddChildToSelection(PRInt32 aIndex)
PRUint32
nsXFormsSelectableAccessible::SelectedItemCount()
{
nsCOMPtr<nsIDOMNode> item = GetItemByIndex(&aIndex);
if (!item)
return NS_OK;
nsresult rv;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element) {
nsCOMPtr<nsIDOMNode> item;
rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(item));
return NS_SUCCEEDED(rv) && item ? 1 : 0;
}
nsCOMPtr<nsIDOMNodeList> itemNodeList;
rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
getter_AddRefs(itemNodeList));
if (NS_FAILED(rv) || !itemNodeList)
return 0;
PRUint32 length = 0;
itemNodeList->GetLength(&length);
return length;
}
bool
nsXFormsSelectableAccessible::AddItemToSelection(PRUint32 aIndex)
{
nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex)));
if (!itemDOMNode)
return false;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element)
return sXFormsService->SetSelectedItemForSelect1(DOMNode, item);
sXFormsService->SetSelectedItemForSelect1(DOMNode, itemDOMNode);
else
sXFormsService->AddItemToSelectionForSelect(DOMNode, itemDOMNode);
return sXFormsService->AddItemToSelectionForSelect(DOMNode, item);
return true;
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::RemoveChildFromSelection(PRInt32 aIndex)
bool
nsXFormsSelectableAccessible::RemoveItemFromSelection(PRUint32 aIndex)
{
nsCOMPtr<nsIDOMNode> item = GetItemByIndex(&aIndex);
if (!item)
return NS_OK;
nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex)));
if (!itemDOMNode)
return false;
nsresult rv;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element) {
nsCOMPtr<nsIDOMNode> selitem;
rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(selitem));
NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNode> selItemDOMNode;
sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(selItemDOMNode));
if (selItemDOMNode == itemDOMNode)
sXFormsService->SetSelectedItemForSelect1(DOMNode, nsnull);
if (selitem != item)
return NS_ERROR_FAILURE;
return sXFormsService->SetSelectedItemForSelect1(DOMNode, nsnull);
return true;
}
return sXFormsService->RemoveItemFromSelectionForSelect(DOMNode, item);
sXFormsService->RemoveItemFromSelectionForSelect(DOMNode, itemDOMNode);
return true;
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::RefSelection(PRInt32 aIndex,
nsIAccessible **aAccessible)
nsAccessible*
nsXFormsSelectableAccessible::GetSelectedItem(PRUint32 aIndex)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
nsresult rv;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element) {
if (aIndex != 0)
return NS_OK;
return nsnull;
nsCOMPtr<nsIDOMNode> item;
nsCOMPtr<nsIDOMNode> itemDOMNode;
rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(item));
NS_ENSURE_SUCCESS(rv, rv);
if (item)
return GetAccService()->GetAccessibleFor(item, aAccessible);
return NS_OK;
getter_AddRefs(itemDOMNode));
if (NS_SUCCEEDED(rv) && itemDOMNode) {
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
return GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
}
return nsnull;
}
nsCOMPtr<nsIDOMNodeList> items;
nsCOMPtr<nsIDOMNodeList> itemNodeList;
rv = sXFormsService->GetSelectedItemsForSelect(DOMNode,
getter_AddRefs(items));
NS_ENSURE_SUCCESS(rv, rv);
getter_AddRefs(itemNodeList));
if (NS_FAILED(rv) || !itemNodeList)
return nsnull;
if (!items)
return NS_OK;
nsCOMPtr<nsIDOMNode> itemDOMNode;
itemNodeList->Item(aIndex, getter_AddRefs(itemDOMNode));
PRUint32 length = 0;
items->GetLength(&length);
if (aIndex < 0 || PRUint32(aIndex) >= length)
return NS_OK;
nsCOMPtr<nsIDOMNode> item;
items->Item(aIndex, getter_AddRefs(item));
nsCOMPtr<nsIAccessible> accessible;
return GetAccService()->GetAccessibleFor(item, getter_AddRefs(accessible));
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemDOMNode));
return GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::IsChildSelected(PRInt32 aIndex,
PRBool *aIsSelected)
bool
nsXFormsSelectableAccessible::IsItemSelected(PRUint32 aIndex)
{
NS_ENSURE_ARG_POINTER(aIsSelected);
*aIsSelected = PR_FALSE;
nsCOMPtr<nsIDOMNode> item = GetItemByIndex(&aIndex);
if (!item)
return NS_OK;
nsCOMPtr<nsIDOMNode> itemDOMNode(do_QueryInterface(GetItemByIndex(&aIndex)));
if (!itemDOMNode)
return false;
nsresult rv;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element) {
nsCOMPtr<nsIDOMNode> selitem;
rv = sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(selitem));
NS_ENSURE_SUCCESS(rv, rv);
if (selitem == item)
*aIsSelected = PR_TRUE;
return NS_OK;
nsCOMPtr<nsIDOMNode> selItemDOMNode;
sXFormsService->GetSelectedItemForSelect1(DOMNode,
getter_AddRefs(selItemDOMNode));
return selItemDOMNode == itemDOMNode;
}
return sXFormsService->IsSelectItemSelected(DOMNode, item, aIsSelected);
PRBool isSelected = PR_FALSE;
sXFormsService->IsSelectItemSelected(DOMNode, itemDOMNode, &isSelected);
return isSelected;
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::ClearSelection()
bool
nsXFormsSelectableAccessible::UnselectAll()
{
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
if (mIsSelect1Element)
return sXFormsService->SetSelectedItemForSelect1(DOMNode, nsnull);
sXFormsService->SetSelectedItemForSelect1(DOMNode, nsnull);
return sXFormsService->ClearSelectionForSelect(DOMNode);
sXFormsService->ClearSelectionForSelect(DOMNode);
return true;
}
NS_IMETHODIMP
nsXFormsSelectableAccessible::SelectAllSelection(PRBool *aMultipleSelection)
bool
nsXFormsSelectableAccessible::SelectAll()
{
NS_ENSURE_ARG_POINTER(aMultipleSelection);
if (mIsSelect1Element)
return false;
if (mIsSelect1Element) {
*aMultipleSelection = PR_FALSE;
return NS_OK;
}
*aMultipleSelection = PR_TRUE;
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
return sXFormsService->SelectAllItemsForSelect(DOMNode);
sXFormsService->SelectAllItemsForSelect(DOMNode);
return true;
}
already_AddRefed<nsIDOMNode>
nsXFormsSelectableAccessible::GetItemByIndex(PRInt32 *aIndex,
nsIAccessible *aAccessible)
nsIContent*
nsXFormsSelectableAccessible::GetItemByIndex(PRUint32* aIndex,
nsAccessible* aAccessible)
{
nsRefPtr<nsAccessible> accessible(do_QueryObject(aAccessible));
if (!accessible)
accessible = this;
nsAccessible* accessible = aAccessible ? aAccessible : this;
PRInt32 childCount = accessible->GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible *child = accessible->GetChildAt(childIdx);
nsCOMPtr<nsIDOMNode> childNode(child->GetDOMNode());
nsCOMPtr<nsIContent> childContent(do_QueryInterface(childNode));
if (!childContent)
continue;
nsIContent* childContent = child->GetContent();
nsINodeInfo *nodeInfo = childContent->NodeInfo();
if (nodeInfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) {
if (nodeInfo->Equals(nsAccessibilityAtoms::item)) {
if (!*aIndex)
return childNode.forget();
return childContent;
--*aIndex;
} else if (nodeInfo->Equals(nsAccessibilityAtoms::choices)) {
nsIDOMNode *itemNode = GetItemByIndex(aIndex, child).get();
if (itemNode)
return itemNode;
nsIContent* itemContent = GetItemByIndex(aIndex, child);
if (itemContent)
return itemContent;
}
}
}

View File

@ -162,12 +162,21 @@ class nsXFormsSelectableAccessible : public nsXFormsEditableAccessible
public:
nsXFormsSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLESELECTABLE
// SelectAccessible
virtual bool IsSelect();
virtual already_AddRefed<nsIArray> SelectedItems();
virtual PRUint32 SelectedItemCount();
virtual nsAccessible* GetSelectedItem(PRUint32 aIndex);
virtual bool IsItemSelected(PRUint32 aIndex);
virtual bool AddItemToSelection(PRUint32 aIndex);
virtual bool RemoveItemFromSelection(PRUint32 aIndex);
virtual bool SelectAll();
virtual bool UnselectAll();
protected:
already_AddRefed<nsIDOMNode> GetItemByIndex(PRInt32 *aIndex,
nsIAccessible *aAccessible = nsnull);
nsIContent* GetItemByIndex(PRUint32* aIndex,
nsAccessible* aAccessible = nsnull);
PRBool mIsSelect1Element;
};

View File

@ -879,7 +879,6 @@ nsXULListitemAccessible::
eCaseMatters);
}
/** Inherit the ISupports impl from nsAccessible, we handle nsIAccessibleSelectable */
NS_IMPL_ISUPPORTS_INHERITED0(nsXULListitemAccessible, nsAccessible)
nsAccessible *

View File

@ -65,7 +65,6 @@ static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
// nsXULSelectableAccessible
////////////////////////////////////////////////////////////////////////////////
// Helper methos
nsXULSelectableAccessible::
nsXULSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
nsAccessibleWrap(aContent, aShell)
@ -73,7 +72,8 @@ nsXULSelectableAccessible::
mSelectControl = do_QueryInterface(aContent);
}
NS_IMPL_ISUPPORTS_INHERITED1(nsXULSelectableAccessible, nsAccessible, nsIAccessibleSelectable)
////////////////////////////////////////////////////////////////////////////////
// nsXULSelectableAccessible: nsAccessNode
void
nsXULSelectableAccessible::Shutdown()
@ -82,51 +82,23 @@ nsXULSelectableAccessible::Shutdown()
nsAccessibleWrap::Shutdown();
}
nsresult nsXULSelectableAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
////////////////////////////////////////////////////////////////////////////////
// nsXULSelectableAccessible: SelectAccessible
bool
nsXULSelectableAccessible::IsSelect()
{
*aSelState = PR_FALSE;
if (!mSelectControl) {
return NS_ERROR_FAILURE;
}
nsAccessible* child = GetChildAt(aIndex);
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMNode> childNode;
child->GetDOMNode(getter_AddRefs(childNode));
nsCOMPtr<nsIDOMXULSelectControlItemElement> item(do_QueryInterface(childNode));
NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
item->GetSelected(aSelState);
if (eSelection_GetState == aMethod) {
return NS_OK;
}
nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
do_QueryInterface(mSelectControl);
if (eSelection_Add == aMethod && !(*aSelState)) {
return xulMultiSelect ? xulMultiSelect->AddItemToSelection(item) :
mSelectControl->SetSelectedItem(item);
}
if (eSelection_Remove == aMethod && (*aSelState)) {
return xulMultiSelect ? xulMultiSelect->RemoveItemFromSelection(item) :
mSelectControl->SetSelectedItem(nsnull);
}
return NS_ERROR_FAILURE;
return !!mSelectControl;
}
// Interface methods
NS_IMETHODIMP nsXULSelectableAccessible::GetSelectedChildren(nsIArray **aChildren)
already_AddRefed<nsIArray>
nsXULSelectableAccessible::SelectedItems()
{
*aChildren = nsnull;
if (!mSelectControl) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIMutableArray> selectedAccessibles =
nsCOMPtr<nsIMutableArray> selectedItems =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_STATE(selectedAccessibles);
if (!selectedItems)
return nsnull;
// For XUL multi-select control
nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
@ -135,129 +107,165 @@ NS_IMETHODIMP nsXULSelectableAccessible::GetSelectedChildren(nsIArray **aChildre
PRInt32 length = 0;
xulMultiSelect->GetSelectedCount(&length);
for (PRInt32 index = 0; index < length; index++) {
nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
xulMultiSelect->GetSelectedItem(index, getter_AddRefs(selectedItem));
nsCOMPtr<nsIContent> selectedContent(do_QueryInterface(selectedItem));
nsAccessible *selectedAcc =
GetAccService()->GetAccessibleInWeakShell(selectedContent, mWeakShell);
if (selectedAcc)
selectedAccessibles->AppendElement(static_cast<nsIAccessible*>(selectedAcc),
PR_FALSE);
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
xulMultiSelect->GetSelectedItem(index, getter_AddRefs(itemElm));
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
nsAccessible* item =
GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
if (item)
selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
PR_FALSE);
}
}
else { // Single select?
nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
mSelectControl->GetSelectedItem(getter_AddRefs(selectedItem));
nsCOMPtr<nsIContent> selectedContent(do_QueryInterface(selectedItem));
if(selectedContent) {
nsAccessible *selectedAcc =
GetAccService()->GetAccessibleInWeakShell(selectedContent, mWeakShell);
if (selectedAcc)
selectedAccessibles->AppendElement(static_cast<nsIAccessible*>(selectedAcc),
PR_FALSE);
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
if(itemNode) {
nsAccessible* item =
GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell);
if (item)
selectedItems->AppendElement(static_cast<nsIAccessible*>(item),
PR_FALSE);
}
}
PRUint32 uLength = 0;
selectedAccessibles->GetLength(&uLength);
if (uLength != 0) { // length of nsIArray containing selected options
NS_ADDREF(*aChildren = selectedAccessibles);
}
return NS_OK;
nsIMutableArray* items = nsnull;
selectedItems.forget(&items);
return items;
}
// return the nth selected child's nsIAccessible object
NS_IMETHODIMP nsXULSelectableAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **aAccessible)
nsAccessible*
nsXULSelectableAccessible::GetSelectedItem(PRUint32 aIndex)
{
*aAccessible = nsnull;
if (!mSelectControl) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
do_QueryInterface(mSelectControl);
if (xulMultiSelect)
xulMultiSelect->GetSelectedItem(aIndex, getter_AddRefs(selectedItem));
if (aIndex == 0)
mSelectControl->GetSelectedItem(getter_AddRefs(selectedItem));
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm;
if (multiSelectControl)
multiSelectControl->GetSelectedItem(aIndex, getter_AddRefs(itemElm));
else if (aIndex == 0)
mSelectControl->GetSelectedItem(getter_AddRefs(itemElm));
if (!selectedItem)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> selectedContent(do_QueryInterface(selectedItem));
nsAccessible *selectedAcc =
GetAccService()->GetAccessibleInWeakShell(selectedContent, mWeakShell);
if (!selectedAcc)
return NS_ERROR_FAILURE;
NS_ADDREF(*aAccessible = selectedAcc);
return NS_OK;
nsCOMPtr<nsINode> itemNode(do_QueryInterface(itemElm));
return itemNode ?
GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell) : nsnull;
}
NS_IMETHODIMP nsXULSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
PRUint32
nsXULSelectableAccessible::SelectedItemCount()
{
*aSelectionCount = 0;
if (!mSelectControl) {
return NS_ERROR_FAILURE;
}
// For XUL multi-select control
nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
do_QueryInterface(mSelectControl);
if (xulMultiSelect)
return xulMultiSelect->GetSelectedCount(aSelectionCount);
if (multiSelectControl) {
PRInt32 count = 0;
multiSelectControl->GetSelectedCount(&count);
return count;
}
// For XUL single-select control/menulist
PRInt32 index;
mSelectControl->GetSelectedIndex(&index);
if (index >= 0)
*aSelectionCount = 1;
return NS_OK;
return (index >= 0) ? 1 : 0;
}
NS_IMETHODIMP nsXULSelectableAccessible::AddChildToSelection(PRInt32 aIndex)
bool
nsXULSelectableAccessible::AddItemToSelection(PRUint32 aIndex)
{
PRBool isSelected;
return ChangeSelection(aIndex, eSelection_Add, &isSelected);
nsAccessible* item = GetChildAt(aIndex);
if (!item)
return false;
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
do_QueryInterface(item->GetContent());
if (!itemElm)
return false;
PRBool isItemSelected = PR_FALSE;
itemElm->GetSelected(&isItemSelected);
if (isItemSelected)
return true;
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
do_QueryInterface(mSelectControl);
if (multiSelectControl)
multiSelectControl->AddItemToSelection(itemElm);
else
mSelectControl->SetSelectedItem(itemElm);
return true;
}
NS_IMETHODIMP nsXULSelectableAccessible::RemoveChildFromSelection(PRInt32 aIndex)
bool
nsXULSelectableAccessible::RemoveItemFromSelection(PRUint32 aIndex)
{
PRBool isSelected;
return ChangeSelection(aIndex, eSelection_Remove, &isSelected);
nsAccessible* item = GetChildAt(aIndex);
if (!item)
return false;
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
do_QueryInterface(item->GetContent());
if (!itemElm)
return false;
PRBool isItemSelected = PR_FALSE;
itemElm->GetSelected(&isItemSelected);
if (!isItemSelected)
return true;
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
do_QueryInterface(mSelectControl);
if (multiSelectControl)
multiSelectControl->RemoveItemFromSelection(itemElm);
else
mSelectControl->SetSelectedItem(nsnull);
return true;
}
NS_IMETHODIMP nsXULSelectableAccessible::IsChildSelected(PRInt32 aIndex, PRBool *aIsSelected)
bool
nsXULSelectableAccessible::IsItemSelected(PRUint32 aIndex)
{
*aIsSelected = PR_FALSE;
return ChangeSelection(aIndex, eSelection_GetState, aIsSelected);
nsAccessible* item = GetChildAt(aIndex);
if (!item)
return false;
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemElm =
do_QueryInterface(item->GetContent());
if (!itemElm)
return false;
PRBool isItemSelected = PR_FALSE;
itemElm->GetSelected(&isItemSelected);
return isItemSelected;
}
NS_IMETHODIMP nsXULSelectableAccessible::ClearSelection()
bool
nsXULSelectableAccessible::UnselectAll()
{
if (!mSelectControl) {
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
do_QueryInterface(mSelectControl);
multiSelectControl ?
multiSelectControl->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
return true;
}
bool
nsXULSelectableAccessible::SelectAll()
{
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelectControl =
do_QueryInterface(mSelectControl);
if (multiSelectControl) {
multiSelectControl->SelectAll();
return true;
}
nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
do_QueryInterface(mSelectControl);
return xulMultiSelect ? xulMultiSelect->ClearSelection() : mSelectControl->SetSelectedIndex(-1);
}
NS_IMETHODIMP nsXULSelectableAccessible::SelectAllSelection(PRBool *aSucceeded)
{
*aSucceeded = PR_TRUE;
nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
do_QueryInterface(mSelectControl);
if (xulMultiSelect)
return xulMultiSelect->SelectAll();
// otherwise, don't support this method
*aSucceeded = PR_FALSE;
return NS_ERROR_NOT_IMPLEMENTED;
return false;
}

View File

@ -40,27 +40,32 @@
#define _nsXULMenuAccessible_H_
#include "nsAccessibleWrap.h"
#include "nsIAccessibleSelectable.h"
#include "nsIDOMXULSelectCntrlEl.h"
/**
* The basic implementation of nsIAccessibleSelectable.
* The basic implementation of SelectAccessible for XUL select controls.
*/
class nsXULSelectableAccessible : public nsAccessibleWrap
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLESELECTABLE
nsXULSelectableAccessible(nsIContent *aContent, nsIWeakReference *aShell);
virtual ~nsXULSelectableAccessible() {}
// nsAccessNode
virtual void Shutdown();
protected:
nsresult ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
// SelectAccessible
virtual bool IsSelect();
virtual already_AddRefed<nsIArray> SelectedItems();
virtual PRUint32 SelectedItemCount();
virtual nsAccessible* GetSelectedItem(PRUint32 aIndex);
virtual bool IsItemSelected(PRUint32 aIndex);
virtual bool AddItemToSelection(PRUint32 aIndex);
virtual bool RemoveItemFromSelection(PRUint32 aIndex);
virtual bool SelectAll();
virtual bool UnselectAll();
protected:
// nsIDOMXULMultiSelectControlElement inherits from this, so we'll always have
// one of these if the widget is valid and not defunct
nsCOMPtr<nsIDOMXULSelectControlElement> mSelectControl;

View File

@ -57,7 +57,7 @@
nsXULTreeAccessible::
nsXULTreeAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
nsXULSelectableAccessible(aContent, aShell)
nsAccessibleWrap(aContent, aShell)
{
mTree = nsCoreUtils::GetTreeBoxObject(aContent);
if (mTree)
@ -85,10 +85,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeAccessible)
NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsXULTreeAccessible)
NS_INTERFACE_MAP_END_INHERITING(nsXULSelectableAccessible)
NS_INTERFACE_MAP_END_INHERITING(nsAccessible)
NS_IMPL_ADDREF_INHERITED(nsXULTreeAccessible, nsXULSelectableAccessible)
NS_IMPL_RELEASE_INHERITED(nsXULTreeAccessible, nsXULSelectableAccessible)
NS_IMPL_ADDREF_INHERITED(nsXULTreeAccessible, nsAccessible)
NS_IMPL_RELEASE_INHERITED(nsXULTreeAccessible, nsAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeAccessible: nsAccessible implementation
@ -160,7 +160,7 @@ nsXULTreeAccessible::GetValue(nsAString& aValue)
PRBool
nsXULTreeAccessible::IsDefunct()
{
return nsXULSelectableAccessible::IsDefunct() || !mTree || !mTreeView;
return nsAccessibleWrap::IsDefunct() || !mTree || !mTreeView;
}
void
@ -175,7 +175,7 @@ nsXULTreeAccessible::Shutdown()
mTree = nsnull;
mTreeView = nsnull;
nsXULSelectableAccessible::Shutdown();
nsAccessibleWrap::Shutdown();
}
////////////////////////////////////////////////////////////////////////////////
@ -262,8 +262,7 @@ nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
// If we failed to find tree cell for the given point then it might be
// tree columns.
if (row == -1 || !column)
return nsXULSelectableAccessible::
GetChildAtPoint(aX, aY, aDeepestChild, aChild);
return nsAccessibleWrap::GetChildAtPoint(aX, aY, aDeepestChild, aChild);
nsAccessible *child = GetTreeItemAccessible(row);
if (aDeepestChild && child) {
@ -280,23 +279,26 @@ nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeAccessible: nsAccessibleSelectable implementation
// nsXULTreeAccessible: SelectAccessible
NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
bool
nsXULTreeAccessible::IsSelect()
{
// Ask tree selection to get all selected children
*_retval = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
return true;
}
already_AddRefed<nsIArray>
nsXULTreeAccessible::SelectedItems()
{
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (!selection)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIMutableArray> selectedAccessibles =
return nsnull;
nsCOMPtr<nsIMutableArray> selectedItems =
do_CreateInstance(NS_ARRAY_CONTRACTID);
NS_ENSURE_STATE(selectedAccessibles);
if (!selectedItems)
return nsnull;
PRInt32 rowIndex, rowCount;
PRBool isSelected;
@ -304,98 +306,95 @@ NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
selection->IsSelected(rowIndex, &isSelected);
if (isSelected) {
nsIAccessible *tempAccessible = GetTreeItemAccessible(rowIndex);
NS_ENSURE_STATE(tempAccessible);
selectedAccessibles->AppendElement(tempAccessible, PR_FALSE);
nsIAccessible* item = GetTreeItemAccessible(rowIndex);
if (item)
selectedItems->AppendElement(item, PR_FALSE);
}
}
PRUint32 length;
selectedAccessibles->GetLength(&length);
if (length != 0) {
*_retval = selectedAccessibles;
NS_IF_ADDREF(*_retval);
}
return NS_OK;
nsIMutableArray* items = nsnull;
selectedItems.forget(&items);
return items;
}
NS_IMETHODIMP nsXULTreeAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
PRUint32
nsXULTreeAccessible::SelectedItemCount()
{
*aSelectionCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (selection)
selection->GetCount(aSelectionCount);
return NS_OK;
}
NS_IMETHODIMP nsXULTreeAccessible::ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (selection) {
selection->IsSelected(aIndex, aSelState);
if ((!(*aSelState) && eSelection_Add == aMethod) ||
((*aSelState) && eSelection_Remove == aMethod))
return selection->ToggleSelect(aIndex);
PRInt32 count = 0;
selection->GetCount(&count);
return count;
}
return NS_OK;
return 0;
}
NS_IMETHODIMP nsXULTreeAccessible::AddChildToSelection(PRInt32 aIndex)
bool
nsXULTreeAccessible::AddItemToSelection(PRUint32 aIndex)
{
PRBool isSelected;
return ChangeSelection(aIndex, eSelection_Add, &isSelected);
}
NS_IMETHODIMP nsXULTreeAccessible::RemoveChildFromSelection(PRInt32 aIndex)
{
PRBool isSelected;
return ChangeSelection(aIndex, eSelection_Remove, &isSelected);
}
NS_IMETHODIMP nsXULTreeAccessible::IsChildSelected(PRInt32 aIndex, PRBool *_retval)
{
return ChangeSelection(aIndex, eSelection_GetState, _retval);
}
NS_IMETHODIMP nsXULTreeAccessible::ClearSelection()
{
if (IsDefunct())
return NS_ERROR_FAILURE;
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (selection)
selection->ClearSelection();
if (selection) {
PRBool isSelected = PR_FALSE;
selection->IsSelected(aIndex, &isSelected);
if (!isSelected)
selection->ToggleSelect(aIndex);
return NS_OK;
return true;
}
return false;
}
NS_IMETHODIMP
nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **aAccessible)
bool
nsXULTreeAccessible::RemoveItemFromSelection(PRUint32 aIndex)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (selection) {
PRBool isSelected = PR_FALSE;
selection->IsSelected(aIndex, &isSelected);
if (isSelected)
selection->ToggleSelect(aIndex);
if (IsDefunct())
return NS_ERROR_FAILURE;
return true;
}
return false;
}
bool
nsXULTreeAccessible::IsItemSelected(PRUint32 aIndex)
{
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (selection) {
PRBool isSelected = PR_FALSE;
selection->IsSelected(aIndex, &isSelected);
return isSelected;
}
return false;
}
bool
nsXULTreeAccessible::UnselectAll()
{
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (!selection)
return NS_ERROR_FAILURE;
return false;
selection->ClearSelection();
return true;
}
nsAccessible*
nsXULTreeAccessible::GetSelectedItem(PRUint32 aIndex)
{
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
if (!selection)
return nsnull;
PRInt32 rowIndex, rowCount;
PRInt32 selCount = 0;
@ -404,26 +403,19 @@ nsXULTreeAccessible::RefSelection(PRInt32 aIndex, nsIAccessible **aAccessible)
for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
selection->IsSelected(rowIndex, &isSelected);
if (isSelected) {
if (selCount == aIndex) {
NS_IF_ADDREF(*aAccessible = GetTreeItemAccessible(rowIndex));
return NS_OK;
}
if (selCount == aIndex)
return GetTreeItemAccessible(rowIndex);
selCount++;
}
}
return NS_OK;
return nsnull;
}
NS_IMETHODIMP
nsXULTreeAccessible::SelectAllSelection(PRBool *aIsMultiSelectable)
bool
nsXULTreeAccessible::SelectAll()
{
NS_ENSURE_ARG_POINTER(aIsMultiSelectable);
*aIsMultiSelectable = PR_FALSE;
if (IsDefunct())
return NS_ERROR_FAILURE;
// see if we are multiple select if so set ourselves as such
nsCOMPtr<nsITreeSelection> selection;
mTreeView->GetSelection(getter_AddRefs(selection));
@ -431,12 +423,12 @@ nsXULTreeAccessible::SelectAllSelection(PRBool *aIsMultiSelectable)
PRBool single = PR_FALSE;
selection->GetSingle(&single);
if (!single) {
*aIsMultiSelectable = PR_TRUE;
selection->SelectAll();
return true;
}
}
return NS_OK;
return false;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -61,7 +61,7 @@ const PRUint32 kDefaultTreeCacheSize = 256;
{ 0xb8, 0xe1, 0x2c, 0x44, 0xb0, 0x41, 0x85, 0xe3 } \
}
class nsXULTreeAccessible : public nsXULSelectableAccessible
class nsXULTreeAccessible : public nsAccessibleWrap
{
public:
using nsAccessible::GetChildCount;
@ -79,9 +79,6 @@ public:
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
// nsIAccessibleSelectable
NS_DECL_NSIACCESSIBLESELECTABLE
// nsAccessNode
virtual PRBool IsDefunct();
virtual void Shutdown();
@ -96,6 +93,17 @@ public:
virtual nsAccessible* GetChildAt(PRUint32 aIndex);
virtual PRInt32 GetChildCount();
// SelectAccessible
virtual bool IsSelect();
virtual already_AddRefed<nsIArray> SelectedItems();
virtual PRUint32 SelectedItemCount();
virtual nsAccessible* GetSelectedItem(PRUint32 aIndex);
virtual bool IsItemSelected(PRUint32 aIndex);
virtual bool AddItemToSelection(PRUint32 aIndex);
virtual bool RemoveItemFromSelection(PRUint32 aIndex);
virtual bool SelectAll();
virtual bool UnselectAll();
// nsXULTreeAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
@ -144,8 +152,6 @@ protected:
nsCOMPtr<nsITreeBoxObject> mTree;
nsCOMPtr<nsITreeView> mTreeView;
nsAccessibleHashtable mAccessibleCache;
NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeAccessible,

View File

@ -4,33 +4,79 @@
* @param aIdentifier [in] selectable container accessible
* @param aSelectedChildren [in] array of selected children
*/
function testSelectableSelection(aIdentifier, aSelectedChildren)
function testSelectableSelection(aIdentifier, aSelectedChildren, aMsg)
{
var acc = getAccessible(aIdentifier, [nsIAccessibleSelectable]);
if (!acc)
return;
var msg = aMsg ? aMsg : "";
var len = aSelectedChildren.length;
// getSelectedChildren
var selectedChildren = acc.GetSelectedChildren();
is(selectedChildren ? selectedChildren.length : 0, aSelectedChildren.length,
"getSelectedChildren: wrong selected children count for " + prettyName(aIdentifier));
is(selectedChildren ? selectedChildren.length : 0, len,
msg + "getSelectedChildren: wrong selected children count for " +
prettyName(aIdentifier));
for (var idx = 0; idx < len; idx++) {
var expectedAcc = getAccessible(aSelectedChildren[idx]);
is(selectedChildren.queryElementAt(idx, nsIAccessible), expectedAcc,
"getSelectedChildren: wrong selected child at index " + idx + " for " + prettyName(aIdentifier));
var actualAcc = selectedChildren.queryElementAt(idx, nsIAccessible);
is(actualAcc, expectedAcc,
msg + "getSelectedChildren: wrong selected child at index " + idx +
" for " + prettyName(aIdentifier) + " { actual : " +
prettyName(actualAcc) + ", expected: " + prettyName(expectedAcc) + "}");
}
// selectionCount
is(acc.selectionCount, aSelectedChildren.length,
"selectionCount: wrong selected children count for " + prettyName(aIdentifier));
// XXX: nsIAccessibleText and nsIAccessibleSelectable both have
// selectionCount property.
//is(acc.selectionCount, aSelectedChildren.length,
// "selectionCount: wrong selected children count for " + prettyName(aIdentifier));
// refSelection
for (var idx = 0; idx < len; idx++) {
var expectedAcc = getAccessible(aSelectedChildren[idx]);
is(acc.refSelection(idx), expectedAcc,
"refSelection: wrong selected child at index " + idx + " for " + prettyName(aIdentifier));
msg + "refSelection: wrong selected child at index " + idx + " for " +
prettyName(aIdentifier));
}
// isChildSelected
testIsChildSelected(acc, acc, { value: 0 }, aSelectedChildren, msg);
}
/**
* Test isChildSelected method, helper for testSelectableSelection
*/
function testIsChildSelected(aSelectAcc, aTraversedAcc, aIndexObj, aSelectedChildren, aMsg)
{
var childCount = aTraversedAcc.childCount;
for (var idx = 0; idx < childCount; idx++) {
var child = aTraversedAcc.getChildAt(idx);
var [state, extraState] = getStates(child);
if (state & STATE_SELECTABLE) {
var isSelected = false;
var len = aSelectedChildren.length;
for (var jdx = 0; jdx < len; jdx++) {
if (child == getAccessible(aSelectedChildren[jdx])) {
isSelected = true;
break;
}
}
// isChildSelected
is(aSelectAcc.isChildSelected(aIndexObj.value++), isSelected,
aMsg + "isChildSelected: wrong selected child " + prettyName(child) +
" for " + prettyName(aSelectAcc));
// selected state
testStates(child, isSelected ? STATE_SELECTED : 0, 0,
!isSelected ? STATE_SELECTED : 0 , 0);
continue;
}
testIsChildSelected(aSelectAcc, child, aIndexObj, aSelectedChildren);
}
}

View File

@ -47,6 +47,9 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_aria.html \
test_listbox.xul \
test_menu.xul \
test_menulist.xul \
test_select.html \
test_tree.xul \
$(NULL)

View File

@ -17,6 +17,8 @@
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript"
src="../selectable.js"></script>
@ -36,32 +38,88 @@
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// role="list"
var id = "list1";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
testSelectableSelection(id, [ ]);
var select = getAccessible(id, [nsIAccessibleSelectable]);
select.addChildToSelection(0);
testSelectableSelection(id, [ ]);
select.removeChildFromSelection(0);
testSelectableSelection(id, [ ]);
select.selectAllSelection();
testSelectableSelection(id, [ ]);
select.clearSelection();
testSelectableSelection(id, [ ]);
//////////////////////////////////////////////////////////////////////////
// role="listbox"
id = "listbox1";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
testSelectableSelection(id, [ ]);
//////////////////////////////////////////////////////////////////////////
// role="listbox" aria-multiselectable
id = "listbox2";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
testSelectableSelection(id, [ ]);
select = getAccessible(id, [nsIAccessibleSelectable]);
select.addChildToSelection(0);
testSelectableSelection(id, [ "listbox2_item1" ]);
select.removeChildFromSelection(0);
testSelectableSelection(id, [ ]);
select.selectAllSelection();
testSelectableSelection(id, [ "listbox2_item1", "listbox2_item2" ]);
select.clearSelection();
testSelectableSelection(id, [ ]);
//////////////////////////////////////////////////////////////////////////
// role="grid"
id = "grid1";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
testSelectableSelection(id, [ ]);
//////////////////////////////////////////////////////////////////////////
// role="tree"
id = "tree1";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
testSelectableSelection(id, [ ]);
//////////////////////////////////////////////////////////////////////////
// role="treegrid"
id = "treegrid1";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
// Test selection methods for selectable children in subtree.
testSelectable("grid2",
testSelectableSelection(id, [ ]);
//////////////////////////////////////////////////////////////////////////
// role="grid" aria-multiselectable, selectable children in subtree
id = "grid2";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
testSelectable(id,
["grid2_colhead1", "grid2_colhead2", "grid2_colhead3",
"grid2_rowhead", "grid2_cell1", "grid2_cell2"]);
@ -86,6 +144,11 @@
title="ARIA grid and accessible selectable methods shouldn't use GetNextSibling">
Mozilla Bug 566551
</a><br>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=590176"
title="add pseudo SelectAccessible interface">
Mozilla Bug 590176
</a><br>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
@ -102,8 +165,8 @@
</div>
<div role="listbox" id="listbox2" aria-multiselectable="true">
<div role="listitem">item1</div>
<div role="listitem">item2</div>
<div role="listitem" id="listbox2_item1">item1</div>
<div role="listitem" id="listbox2_item2">item2</div>
</div>
<div role="grid" id="grid1">

View File

@ -0,0 +1,155 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/treeview.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="XUL tree selectable tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../states.js" />
<script type="application/javascript"
src="../selectable.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
//gA11yEventDumpID = "debug";
var gQueue = null;
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// single selectable listbox
var id = "listbox";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for list of " + id);
var select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ ]);
select.addChildToSelection(1);
testSelectableSelection(select, [ "lb1_item2" ], "addChildToSelect(1): ");
select.removeChildFromSelection(1);
testSelectableSelection(select, [ ],
"removeChildFromSelection(1): ");
todo(select.selectAllSelection() == false,
"No way to select all items in listbox '" + id + "'");
testSelectableSelection(select, [ "lb1_item1" ], "selectAllSelection: ");
select.addChildToSelection(1);
select.clearSelection();
testSelectableSelection(select, [ ], "clearSelection: ");
//////////////////////////////////////////////////////////////////////////
// multiple selectable listbox
var id = "listbox2";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for list of " + id);
var select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ ]);
select.addChildToSelection(1);
testSelectableSelection(select, [ "lb2_item2" ], "addChildToSelect(1): ");
select.removeChildFromSelection(1);
testSelectableSelection(select, [ ],
"removeChildFromSelection(1): ");
is(select.selectAllSelection(), true,
"All items should be selected in listbox '" + id + "'");
testSelectableSelection(select, [ "lb2_item1", "lb2_item2" ],
"selectAllSelection: ");
select.clearSelection();
testSelectableSelection(select, [ ], "clearSelection: ");
//////////////////////////////////////////////////////////////////////////
// listbox with headers
// XXX: addChildToSelection/removeChildFromSelection don't work correctly
// on listboxes with headers because header is inserted into hierarchy
// and child indexes that are used in these methods are shifted (see bug
// 591939).
todo(false,
"Fix addChildToSelection/removeChildFromSelection on listboxes with headers.");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=590176"
title="add pseudo SelectAccessible interface">
Mozilla Bug 590176
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<listbox id="listbox">
<listcols>
<listcol flex="1"/>
<listcol flex="1"/>
</listcols>
<listitem id="lb1_item1">
<listcell label="cell0"/>
<listcell label="cell1"/>
</listitem>
<listitem id="lb1_item2">
<listcell label="cell3"/>
<listcell label="cell4"/>
</listitem>
</listbox>
<listbox id="listbox2" seltype="multiple">
<listcols>
<listcol flex="1"/>
<listcol flex="1"/>
</listcols>
<listitem id="lb2_item1">
<listcell label="cell0"/>
<listcell label="cell1"/>
</listitem>
<listitem id="lb2_item2">
<listcell label="cell3"/>
<listcell label="cell4"/>
</listitem>
</listbox>
<vbox id="debug"/>
</vbox>
</hbox>
</window>

View File

@ -0,0 +1,81 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/treeview.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="XUL tree selectable tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../states.js" />
<script type="application/javascript"
src="../selectable.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
//gA11yEventDumpID = "debug";
var gQueue = null;
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// menu
var id = "menu";
var menu = getAccessible("menu");
var menuList = menu.firstChild;
todo(isAccessible(menuList, [nsIAccessibleSelectable]),
"No selectable accessible for list of menu '" + id + "'");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=590176"
title="add pseudo SelectAccessible interface">
Mozilla Bug 590176
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<menu label="menu" id="menu">
<menupopup>
<menuitem label="item1" id="m_item1"/>
<menuitem label="item2" id="m_item2"/>
</menupopup>
</menu>
<vbox id="debug"/>
</vbox>
</hbox>
</window>

View File

@ -0,0 +1,99 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/treeview.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="XUL tree selectable tests">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../states.js" />
<script type="application/javascript"
src="../selectable.js" />
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Test
//gA11yEventDumpID = "debug";
var gQueue = null;
function doTest()
{
//////////////////////////////////////////////////////////////////////////
// menulist aka combobox
var id = "combobox";
var combobox = getAccessible(id);
var comboboxList = combobox.firstChild;
ok(isAccessible(comboboxList, [nsIAccessibleSelectable]),
"No selectable accessible for list of " + id);
var select = getAccessible(comboboxList, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ "cb1_item1" ]);
select.addChildToSelection(1);
testSelectableSelection(select, [ "cb1_item2" ], "addChildToSelect(1): ");
select.removeChildFromSelection(1);
testSelectableSelection(select, [ ],
"removeChildFromSelection(1): ");
is(select.selectAllSelection(), false,
"No way to select all items in combobox '" + id + "'");
testSelectableSelection(select, [ ], "selectAllSelection: ");
select.addChildToSelection(1);
select.clearSelection();
testSelectableSelection(select, [ ], "clearSelection: ");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
]]>
</script>
<hbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=590176"
title="add pseudo SelectAccessible interface">
Mozilla Bug 590176
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<menulist id="combobox">
<menupopup>
<menuitem id="cb1_item1" label="item1"/>
<menuitem id="cb1_item2" label="item2"/>
</menupopup>
</menulist>
<vbox id="debug"/>
</vbox>
</hbox>
</window>

View File

@ -17,20 +17,168 @@
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript"
src="../selectable.js"></script>
<script type="application/javascript">
function doTest()
{
var combobox = getAccessible("combobox");
//////////////////////////////////////////////////////////////////////////
// select@size="1" aka combobox
var id = "combobox";
var combobox = getAccessible(id);
var comboboxList = combobox.firstChild;
ok(isAccessible(comboboxList, [nsIAccessibleSelectable]),
"No selectable accessible for list of " + id);
var select = getAccessible(comboboxList, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ "cb1_item1" ]);
// select 2nd item
select.addChildToSelection(1);
testSelectableSelection(select, [ "cb1_item2" ], "addChildToSelect(1): ");
// unselect 2nd item, 1st item gets selected automatically
select.removeChildFromSelection(1);
testSelectableSelection(select, [ "cb1_item1" ],
"removeChildFromSelection(1): ");
// doesn't change selection
is(select.selectAllSelection(), false,
"No way to select all items in combobox '" + id + "'");
testSelectableSelection(select, [ "cb1_item1" ], "selectAllSelection: ");
// doesn't change selection
select.clearSelection();
testSelectableSelection(select, [ "cb1_item1" ], "clearSelection: ");
//////////////////////////////////////////////////////////////////////////
// select@size="1" with optgroups
id = "combobox2";
combobox = getAccessible(id);
comboboxList = combobox.firstChild;
ok(isAccessible(comboboxList, [nsIAccessibleSelectable]),
"No selectable accessible for list of " + id);
select = getAccessible(comboboxList, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ "cb2_item1" ]);
select.addChildToSelection(1);
testSelectableSelection(select, [ "cb2_item2" ]);
select.removeChildFromSelection(1);
testSelectableSelection(select, [ "cb2_item1" ]);
is(select.selectAllSelection(), false,
"No way to select all items in combobox " + id + "'");
testSelectableSelection(select, [ "cb2_item1" ]);
select.clearSelection();
testSelectableSelection(select, [ "cb2_item1" ]);
//////////////////////////////////////////////////////////////////////////
// select@size="4" aka single selectable listbox
var id = "listbox";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ ]);
// select 2nd item
select.addChildToSelection(1);
testSelectableSelection(select, [ "lb1_item2" ], "addChildToSelect(1): ");
// unselect 2nd item, 1st item gets selected automatically
select.removeChildFromSelection(1);
testSelectableSelection(select, [ ],
"removeChildFromSelection(1): ");
// doesn't change selection
is(select.selectAllSelection(), false,
"No way to select all items in single selectable listbox '" + id + "'");
testSelectableSelection(select, [ ], "selectAllSelection: ");
// doesn't change selection
select.clearSelection();
testSelectableSelection(select, [ ], "clearSelection: ");
//////////////////////////////////////////////////////////////////////////
// select@size="4" with optgroups, single selectable
id = "listbox2";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ ]);
select.addChildToSelection(1);
testSelectableSelection(select, [ "lb2_item2" ]);
select.removeChildFromSelection(1);
testSelectableSelection(select, [ ]);
is(select.selectAllSelection(), false,
"No way to select all items in single selectable listbox " + id + "'");
testSelectableSelection(select, [ ]);
select.clearSelection();
testSelectableSelection(select, [ ]);
//////////////////////////////////////////////////////////////////////////
// select@size="4" multiselect aka listbox
id = "listbox3";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ ]);
select.addChildToSelection(0);
testSelectableSelection(select, [ "lb3_item1" ], "addChildToSelection: ");
select.removeChildFromSelection(0);
testSelectableSelection(select, [ ], "removeChildFromSelection: ");
is(select.selectAllSelection(), true,
"All items in listbox '" + id + "' should be selected");
testSelectableSelection(select, [ "lb3_item1", "lb3_item2"],
"selectAllSelection: ");
select.clearSelection();
testSelectableSelection(select, [ ], "clearSelection: ");
//////////////////////////////////////////////////////////////////////////
// select@size="4" multiselect with optgroups
var id = "listbox4";
ok(isAccessible(id, [nsIAccessibleSelectable]),
"No selectable accessible for " + id);
select = getAccessible(id, [nsIAccessibleSelectable]);
testSelectableSelection(select, [ ]);
select.addChildToSelection(0);
testSelectableSelection(select, [ "lb4_item1" ]);
select.removeChildFromSelection(0);
testSelectableSelection(select, [ ]);
is(select.selectAllSelection(), true,
"All items in listbox '" + id + "' should be selected");
testSelectableSelection(select, [ "lb4_item1", "lb4_item2"]);
select.clearSelection();
testSelectableSelection(select, [ ]);
SimpleTest.finish();
}
@ -47,19 +195,50 @@
title="ARIA single selectable widget should implement nsIAccessibleSelectable">
Mozilla Bug 530014
</a><br>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=590176"
title="add pseudo SelectAccessible interface">
Mozilla Bug 590176
</a><br>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<select id="combobox">
<option>option</option>
<option>option</option>
<option id="cb1_item1">option1</option>
<option id="cb1_item2">option2</option>
</select>
<select id="combobox2">
<option id="cb2_item1">option1</option>
<optgroup>optgroup
<option id="cb2_item2">option2</option>
</optgroup>
</select>
<select id="listbox" size="4">
<option>option</option>
<option>option</option>
<option id="lb1_item1">option1</option>
<option id="lb1_item2">option2</option>
</select>
<select id="listbox2" size="4">
<option id="lb2_item1">option1</option>
<optgroup>optgroup>
<option id="lb2_item2">option2</option>
</optgroup>
</select>
<select id="listbox3" size="4" multiple="true">
<option id="lb3_item1">option1</option>
<option id="lb3_item2">option2</option>
</select>
<select id="listbox4" size="4" multiple="true">
<option id="lb4_item1">option1</option>
<optgroup>optgroup>
<option id="lb4_item2">option2</option>
</optgroup>
</select>
</body>