Bug 383355 State incorrectly set for showing item in a collapsed XUL menulistr=aaronleventhal

This commit is contained in:
ginn.chen@sun.com 2007-06-13 03:54:07 -07:00
Родитель 6b0ee575fd
Коммит ffb1a4af7a
3 изменённых файлов: 74 добавлений и 34 удалений

Просмотреть файл

@ -602,8 +602,9 @@ nsHTMLSelectOptionAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
return rv;
}
PRUint32 selectState;
nsCOMPtr<nsIContent> selectContent = GetSelectState(&selectState);
PRUint32 selectState, selectExtState;
nsCOMPtr<nsIContent> selectContent = GetSelectState(&selectState,
&selectExtState);
if (selectState & nsIAccessibleStates::STATE_INVISIBLE) {
return NS_OK;
}
@ -611,37 +612,37 @@ nsHTMLSelectOptionAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
nsCOMPtr<nsIDOMNode> selectNode = do_QueryInterface(selectContent);
NS_ENSURE_TRUE(selectNode, NS_ERROR_FAILURE);
// find out if we are the focused node
nsCOMPtr<nsIDOMNode> focusedOptionNode;
GetFocusedOptionNode(selectNode, getter_AddRefs(focusedOptionNode));
if (focusedOptionNode == mDOMNode)
*aState |= nsIAccessibleStates::STATE_FOCUSED;
// Is disabled?
if (0 == (*aState & nsIAccessibleStates::STATE_UNAVAILABLE)) {
*aState |= (nsIAccessibleStates::STATE_FOCUSABLE |
nsIAccessibleStates::STATE_SELECTABLE);
}
// Are we selected?
nsCOMPtr<nsIDOMHTMLOptionElement> option (do_QueryInterface(mDOMNode));
if (option && Role(this) != nsIAccessibleRole::ROLE_COMBOBOX_LISTITEM) {
*aState |= nsIAccessibleStates::STATE_SELECTABLE;
PRBool isSelected = PR_FALSE;
nsCOMPtr<nsIDOMHTMLOptionElement> option (do_QueryInterface(mDOMNode));
if (option) {
option->GetSelected(&isSelected);
if ( isSelected )
*aState |= nsIAccessibleStates::STATE_SELECTED;
}
*aState |= nsIAccessibleStates::STATE_FOCUSABLE;
if (selectState & nsIAccessibleStates::STATE_OFFSCREEN) {
*aState |= nsIAccessibleStates::STATE_OFFSCREEN;
}
else if (selectState & nsIAccessibleStates::STATE_COLLAPSED) {
// <select> is COLLAPSED: add STATE_OFFSCREEN, if not the currently
// visible option
if (focusedOptionNode != mDOMNode) {
if (!isSelected) {
*aState |= nsIAccessibleStates::STATE_OFFSCREEN;
}
else {
// Clear offscreen and invisible for currently showing option
*aState &= ~nsIAccessibleStates::STATE_OFFSCREEN;
*aState &= ~nsIAccessibleStates::STATE_INVISIBLE;
if (aExtraState) {
*aExtraState |= selectExtState & nsIAccessibleStates::EXT_STATE_OPAQUE;
}
}
}
else {
@ -831,7 +832,8 @@ void nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibl
privateMultiSelect->FireToolkitEvent(eventType, optionAccessible, nsnull);
}
nsIContent* nsHTMLSelectOptionAccessible::GetSelectState(PRUint32* aState)
nsIContent* nsHTMLSelectOptionAccessible::GetSelectState(PRUint32* aState,
PRUint32* aExtraState)
{
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
while (content && content->Tag() != nsAccessibilityAtoms::select) {
@ -845,8 +847,7 @@ nsIContent* nsHTMLSelectOptionAccessible::GetSelectState(PRUint32* aState)
nsCOMPtr<nsIAccessible> selAcc;
accService->GetAccessibleFor(selectNode, getter_AddRefs(selAcc));
if (selAcc) {
PRUint32 dummy;
selAcc->GetFinalState(aState, &dummy);
selAcc->GetFinalState(aState, aExtraState);
return content;
}
}

Просмотреть файл

@ -174,9 +174,10 @@ private:
/**
* Get Select element's accessible state
* @param aState, Select element state
* @param aExtraState, Select element extra state
* @return Select element content, returns null if not avaliable
*/
nsIContent* GetSelectState(PRUint32* aState);
nsIContent* GetSelectState(PRUint32* aState, PRUint32* aExtraState = nsnull);
};
/*

Просмотреть файл

@ -317,17 +317,54 @@ nsXULMenuitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
}
}
// Offscreen?
// If parent or grandparent menuitem is offscreen, then we're offscreen too
// We get it by replacing the current offscreen bit with the parent's
// Combo box listitem
if (Role(this) == nsIAccessibleRole::ROLE_COMBOBOX_LISTITEM) {
// Is selected?
PRBool isSelected = PR_FALSE;
nsCOMPtr<nsIDOMXULSelectControlItemElement>
item(do_QueryInterface(mDOMNode));
NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
item->GetSelected(&isSelected);
// Is collapsed?
PRBool isCollapsed = PR_FALSE;
nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
if (parentAccessible) {
// clear the old OFFSCREEN bit
*aState &= ~nsIAccessibleStates::STATE_OFFSCREEN;
// or it with the parent's offscreen bit
*aState |= (State(parentAccessible) & nsIAccessibleStates::STATE_OFFSCREEN);
if (parentAccessible &&
State(parentAccessible) & nsIAccessibleStates::STATE_INVISIBLE) {
isCollapsed = PR_TRUE;
}
// Is disabled?
if (0 == (*aState & nsIAccessibleStates::STATE_UNAVAILABLE)) {
*aState |= (nsIAccessibleStates::STATE_FOCUSABLE |
nsIAccessibleStates::STATE_SELECTABLE);
}
if (isSelected) {
*aState |= nsIAccessibleStates::STATE_SELECTED;
// Selected and collapsed?
if (isCollapsed) {
// Set selected option offscreen/invisible according to combobox state
nsCOMPtr<nsIAccessible> grandParentAcc;
parentAccessible->GetParent(getter_AddRefs(grandParentAcc));
NS_ENSURE_TRUE(grandParentAcc, NS_ERROR_FAILURE);
NS_ASSERTION((Role(grandParentAcc) == nsIAccessibleRole::ROLE_COMBOBOX),
"grandparent of combobox listitem is not combobox");
PRUint32 grandParentState, grandParentExtState;
grandParentAcc->GetFinalState(&grandParentState, &grandParentExtState);
*aState &= ~(nsIAccessibleStates::STATE_OFFSCREEN |
nsIAccessibleStates::STATE_INVISIBLE);
*aState |= grandParentState & nsIAccessibleStates::STATE_OFFSCREEN |
grandParentState & nsIAccessibleStates::STATE_INVISIBLE;
if (aExtraState) {
*aExtraState |=
grandParentExtState & nsIAccessibleStates::EXT_STATE_OPAQUE;
}
} // isCollapsed
} // isSelected
} // ROLE_COMBOBOX_LISTITEM
return NS_OK;
}
@ -505,11 +542,12 @@ nsXULMenuitemAccessible(aDOMNode, aShell)
NS_IMETHODIMP
nsXULMenuSeparatorAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
{
// Isn't focusable, but can be offscreen
// Isn't focusable, but can be offscreen/invisible -- only copy those states
nsresult rv = nsXULMenuitemAccessible::GetState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
*aState &= nsIAccessibleStates::STATE_OFFSCREEN;
*aState &= (nsIAccessibleStates::STATE_OFFSCREEN |
nsIAccessibleStates::STATE_INVISIBLE);
return NS_OK;
}
@ -554,11 +592,10 @@ nsXULMenupopupAccessible::nsXULMenupopupAccessible(nsIDOMNode* aDOMNode, nsIWeak
NS_IMETHODIMP
nsXULMenupopupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
{
// We are onscreen if our parent is active
*aState = 0;
if (aExtraState)
*aExtraState = 0;
nsresult rv = nsAccessible::GetState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
// We are onscreen if our parent is active
PRBool isActive = PR_FALSE;
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
@ -575,7 +612,8 @@ nsXULMenupopupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
}
if (!isActive)
*aState |= nsIAccessibleStates::STATE_OFFSCREEN;
*aState |= (nsIAccessibleStates::STATE_OFFSCREEN |
nsIAccessibleStates::STATE_INVISIBLE);
return NS_OK;
}