Bug 341462. XUL menuitems should not fire accessible focus for mouseover. Patch by Ginn Chen. r=aaronlev

This commit is contained in:
aaronleventhal%moonset.net 2006-08-08 14:01:19 +00:00
parent ffa95dbed8
commit 91b403086b
5 changed files with 51 additions and 43 deletions

View File

@ -425,16 +425,11 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireToolkitEvent(PRUint32 aEvent,
*/
case nsIAccessibleEvent::EVENT_MENUSTART:
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUSTART\n"));
atk_focus_tracker_notify(accWrap->GetAtkObject());
g_signal_emit_by_name(accWrap->GetAtkObject(),
"selection_changed");
rv = NS_OK;
break;
case nsIAccessibleEvent::EVENT_MENUEND:
MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUEND\n"));
g_signal_emit_by_name(accWrap->GetAtkObject(),
"selection_changed");
rv = NS_OK;
break;

View File

@ -417,8 +417,10 @@ void nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
// stays outside on that binding parent.
nsCOMPtr<nsIDOMEventTarget> domEventTarget;
nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
nsCOMPtr<nsIDOMNode> realFocusedNode = do_QueryInterface(domEventTarget);
mCaretAccessible->AttachNewSelectionListener(realFocusedNode);
nsCOMPtr<nsIDOMNode> realFocusedNode(do_QueryInterface(domEventTarget));
if (realFocusedNode) {
mCaretAccessible->AttachNewSelectionListener(realFocusedNode);
}
}
}
@ -498,7 +500,7 @@ void nsRootAccessible::FireCurrentFocusEvent()
NS_LITERAL_STRING("Events"),
getter_AddRefs(event))) &&
NS_SUCCEEDED(event->InitEvent(NS_LITERAL_STRING("focus"), PR_TRUE, PR_TRUE))) {
HandleEvent(event);
HandleEventWithTarget(event, focusedNode);
}
}
}
@ -514,7 +516,13 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
GetTargetNode(aEvent, getter_AddRefs(targetNode));
if (!targetNode)
return NS_ERROR_FAILURE;
return HandleEventWithTarget(aEvent, targetNode);
}
NS_IMETHODIMP nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
nsCOMPtr<nsIDOMNode> targetNode)
{
nsAutoString eventType;
aEvent->GetType(eventType);
nsAutoString localName;
@ -656,25 +664,7 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
}
else
#endif
if (eventType.LowerCaseEqualsLiteral("dommenuitemactive")) {
nsCOMPtr<nsIAccessible> containerAccessible = accessible;
PRUint32 containerState = 0;
do {
nsIAccessible *tempAccessible = containerAccessible;
tempAccessible->GetParent(getter_AddRefs(containerAccessible));
if (!containerAccessible) {
break;
}
containerAccessible->GetFinalState(&containerState);
}
while ((containerState & STATE_HASPOPUP) == 0);
// Only fire focus event for DOMMenuItemActive is not inside collapsed popup
if (0 == (containerState & STATE_COLLAPSED)) {
FireAccessibleFocusEvent(accessible, targetNode, aEvent, PR_TRUE);
}
}
else if (eventType.LowerCaseEqualsLiteral("focus")) {
if (eventType.LowerCaseEqualsLiteral("focus")) {
nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
do_QueryInterface(targetNode);
// Send focus to individual radio button or selected item
@ -739,12 +729,6 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
FireAccessibleFocusEvent(accessible, targetNode, aEvent);
}
}
else if (eventType.LowerCaseEqualsLiteral("dommenubaractive"))
privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_MENUSTART, accessible, nsnull);
else if (eventType.LowerCaseEqualsLiteral("dommenubarinactive")) {
privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_MENUEND, accessible, nsnull);
FireCurrentFocusEvent();
}
else if (eventType.LowerCaseEqualsLiteral("popuphiding")) {
// If accessible focus was inside popup that closes,
// then restore it to true current focus.
@ -770,8 +754,7 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
}
#else
AtkStateChange stateData;
if (eventType.LowerCaseEqualsLiteral("focus") ||
eventType.LowerCaseEqualsLiteral("dommenuitemactive")) {
if (eventType.LowerCaseEqualsLiteral("focus")) {
if (treeItemAccessible) { // use focused treeitem
privAcc = do_QueryInterface(treeItemAccessible);
privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_FOCUS,
@ -863,6 +846,33 @@ NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
//FireAccessibleFocusEvent(accessible, targetNode); // Not yet used in ATK
}
#endif
else if (eventType.LowerCaseEqualsLiteral("dommenuitemactive")) {
nsCOMPtr<nsIAccessible> containerAccessible;
accessible->GetParent(getter_AddRefs(containerAccessible));
NS_ENSURE_TRUE(containerAccessible, NS_OK);
if (Role(containerAccessible) == ROLE_MENUBAR) {
// It is top level menuitem
// Only fire focus event if it is not collapsed
if (State(accessible) & STATE_COLLAPSED)
return NS_OK;
}
else {
// It is not top level menuitem
// Only fire focus event if it is not inside collapsed popup
if (State(containerAccessible) & STATE_COLLAPSED)
return NS_OK;
}
FireAccessibleFocusEvent(accessible, targetNode, aEvent, PR_TRUE);
}
else if (eventType.LowerCaseEqualsLiteral("dommenubaractive")) {
privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_MENUSTART,
accessible, nsnull);
}
else if (eventType.LowerCaseEqualsLiteral("dommenubarinactive")) {
privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_MENUEND,
accessible, nsnull);
FireCurrentFocusEvent();
}
return NS_OK;
}

View File

@ -90,6 +90,8 @@ class nsRootAccessible : public nsDocAccessibleWrap,
private:
nsCOMPtr<nsITimer> mFireFocusTimer;
NS_IMETHOD HandleEventWithTarget(nsIDOMEvent* aEvent,
nsCOMPtr<nsIDOMNode> aTargetNode);
static void FireFocusCallback(nsITimer *aTimer, void *aClosure);
protected:

View File

@ -72,8 +72,12 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetState(PRUint32 *_retval)
// Has Popup?
nsAutoString tagName;
element->GetLocalName(tagName);
if (tagName.EqualsLiteral("menu"))
if (tagName.EqualsLiteral("menu")) {
*_retval |= STATE_HASPOPUP;
PRBool isOpen;
element->HasAttribute(NS_LITERAL_STRING("open"), &isOpen);
*_retval |= isOpen ? STATE_EXPANDED : STATE_COLLAPSED;
}
nsAutoString menuItemType;
element->GetAttribute(NS_LITERAL_STRING("type"), menuItemType);
@ -95,15 +99,11 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetState(PRUint32 *_retval)
// 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
PRUint32 parentState = 0;
nsCOMPtr<nsIAccessible> parentAccessible;
GetParent(getter_AddRefs(parentAccessible));
if (parentAccessible) {
GetParent(getter_AddRefs(parentAccessible));
if (parentAccessible) {
parentAccessible->GetFinalState(&parentState);
*_retval &= ~STATE_OFFSCREEN; // clear the old OFFSCREEN bit
*_retval |= (parentState & STATE_OFFSCREEN); // or it with the parent's offscreen bit
}
*_retval &= ~STATE_OFFSCREEN; // clear the old OFFSCREEN bit
*_retval |= (State(parentAccessible) & STATE_OFFSCREEN); // or it with the parent's offscreen bit
}
return NS_OK;

View File

@ -727,6 +727,7 @@ nsMenuFrame::OpenMenu(PRBool aActivateFlag)
MarkAsGenerated();
mContent->SetAttr(kNameSpaceID_None, nsXULAtoms::open, NS_LITERAL_STRING("true"), PR_TRUE);
FireDOMEventSynch(NS_LITERAL_STRING("DOMMenuItemActive"));
}
else mContent->UnsetAttr(kNameSpaceID_None, nsXULAtoms::open, PR_TRUE);
OpenMenuInternal(aActivateFlag);