From 76a90a1e17dcacecf888941a4c2a985b1c4ec8c7 Mon Sep 17 00:00:00 2001 From: "louie.zhao%sun.com" Date: Tue, 1 Feb 2005 09:40:36 +0000 Subject: [PATCH] bug277888 GOK can't work with mozilla modal dialog r = aaronleventhal sr = Henry.Jia --- accessible/src/base/nsAccessNode.cpp | 3 ++ accessible/src/base/nsAccessNode.h | 2 + accessible/src/base/nsAccessible.cpp | 47 +++++++++++++++++++ accessible/src/base/nsAccessible.h | 4 ++ .../src/html/nsHTMLFormControlAccessible.cpp | 6 +-- .../src/xul/nsXULFormControlAccessible.cpp | 21 ++------- accessible/src/xul/nsXULMenuAccessible.cpp | 5 +- accessible/src/xul/nsXULTreeAccessible.cpp | 6 +-- 8 files changed, 62 insertions(+), 32 deletions(-) diff --git a/accessible/src/base/nsAccessNode.cpp b/accessible/src/base/nsAccessNode.cpp index ad40920592d6..0c5c62444135 100755 --- a/accessible/src/base/nsAccessNode.cpp +++ b/accessible/src/base/nsAccessNode.cpp @@ -57,6 +57,7 @@ #include "nsIPresShell.h" #include "nsIServiceManager.h" #include "nsIStringBundle.h" +#include "nsITimer.h" /* For documentation of the accessibility architecture, * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html @@ -64,6 +65,7 @@ nsIStringBundle *nsAccessNode::gStringBundle = 0; nsIStringBundle *nsAccessNode::gKeyStringBundle = 0; +nsITimer *nsAccessNode::gDoCommandTimer = 0; nsIDOMNode *nsAccessNode::gLastFocusedNode = 0; PRBool nsAccessNode::gIsAccessibilityActive = PR_FALSE; PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE; @@ -204,6 +206,7 @@ void nsAccessNode::ShutdownXPAccessibility() } NS_IF_RELEASE(gStringBundle); NS_IF_RELEASE(gKeyStringBundle); + NS_IF_RELEASE(gDoCommandTimer); NS_IF_RELEASE(gLastFocusedNode); ClearCache(gGlobalDocAccessibleCache); diff --git a/accessible/src/base/nsAccessNode.h b/accessible/src/base/nsAccessNode.h index a18c9604dbff..bee3c8b43638 100755 --- a/accessible/src/base/nsAccessNode.h +++ b/accessible/src/base/nsAccessNode.h @@ -57,6 +57,7 @@ class nsPresContext; class nsIAccessibleDocument; class nsIFrame; class nsIDOMNodeList; +class nsITimer; enum { eChildCountUninitialized = 0xffff }; @@ -140,6 +141,7 @@ protected: // Static data, we do our own refcounting for our static data static nsIStringBundle *gStringBundle; static nsIStringBundle *gKeyStringBundle; + static nsITimer *gDoCommandTimer; static PRBool gIsAccessibilityActive; static PRBool gIsCacheDisabled; diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index d18c72533bdb..f825bd45cf8d 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -85,6 +85,7 @@ #include "nsIURI.h" #include "nsIImageLoadingContent.h" #include "nsINameSpaceManager.h" +#include "nsITimer.h" #ifdef NS_DEBUG #include "nsIFrameDebug.h" @@ -1503,6 +1504,52 @@ NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible) return NS_ERROR_NOT_IMPLEMENTED; } +void nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure) +{ + NS_ASSERTION(gDoCommandTimer, "How did we get here if there was no gDoCommandTimer?"); + NS_RELEASE(gDoCommandTimer); + gDoCommandTimer = nsnull; + + nsIDOMNode *node = NS_REINTERPRET_CAST(nsIDOMNode*, aClosure); + nsCOMPtr xulElement(do_QueryInterface(node)); + if (xulElement) { + xulElement->Click(); + } + else { + nsCOMPtr htmlElement(do_QueryInterface(node)); + if (htmlElement) + htmlElement->Click(); + } +} + +/* + * Use Timer to execute "Click" command of XUL/HTML element (e.g. menuitem, button...). + * + * When "Click" is to open a "modal" dialog/window, it won't return untill the + * dialog/window is closed. If executing "Click" command directly in + * nsXXXAccessible::DoAction, it will block AT-Tools(e.g. GOK) that invoke + * "action" of mozilla accessibles direclty. + */ +nsresult nsAccessible::DoCommand() + +{ + if (gDoCommandTimer) { + // Already have timer going for another command + NS_WARNING("Doubling up on do command timers doesn't work. This wasn't expected."); + return NS_ERROR_FAILURE; + } + + nsCOMPtr timer = do_CreateInstance("@mozilla.org/timer;1"); + if (!timer) { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(gDoCommandTimer = timer); + return gDoCommandTimer->InitWithFuncCallback(DoCommandCallback, + (void*)mDOMNode, 0, + nsITimer::TYPE_ONE_SHOT); +} + #ifdef MOZ_ACCESSIBILITY_ATK // static helper functions nsresult nsAccessible::GetParentBlockNode(nsIPresShell *aPresShell, nsIDOMNode *aCurrentNode, nsIDOMNode **aBlockNode) diff --git a/accessible/src/base/nsAccessible.h b/accessible/src/base/nsAccessible.h index 8baaa70ee619..c50281ec4f2a 100644 --- a/accessible/src/base/nsAccessible.h +++ b/accessible/src/base/nsAccessible.h @@ -136,6 +136,10 @@ protected: nsresult AppendFlatStringFromSubtreeRecurse(nsIContent *aContent, nsAString *aFlatString); virtual void CacheChildren(PRBool aWalkAnonContent); + // For accessibles that have actions + static void DoCommandCallback(nsITimer *aTimer, void *aClosure); + nsresult DoCommand(); + // Data Members nsCOMPtr mParent; nsIAccessible *mFirstChild, *mNextSibling; diff --git a/accessible/src/html/nsHTMLFormControlAccessible.cpp b/accessible/src/html/nsHTMLFormControlAccessible.cpp index 81f4ebd9df27..936cbd4c4c6d 100644 --- a/accessible/src/html/nsHTMLFormControlAccessible.cpp +++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp @@ -169,11 +169,7 @@ NS_IMETHODIMP nsHTMLButtonAccessible::GetActionName(PRUint8 index, nsAString& _r NS_IMETHODIMP nsHTMLButtonAccessible::DoAction(PRUint8 index) { if (index == eAction_Click) { - nsCOMPtr element(do_QueryInterface(mDOMNode)); - if (element) { - element->Click(); - return NS_OK; - } + return DoCommand(); } return NS_ERROR_INVALID_ARG; } diff --git a/accessible/src/xul/nsXULFormControlAccessible.cpp b/accessible/src/xul/nsXULFormControlAccessible.cpp index 306a115df1a6..81fc32a5b621 100644 --- a/accessible/src/xul/nsXULFormControlAccessible.cpp +++ b/accessible/src/xul/nsXULFormControlAccessible.cpp @@ -94,13 +94,7 @@ NS_IMETHODIMP nsXULButtonAccessible::GetActionName(PRUint8 index, nsAString& _re NS_IMETHODIMP nsXULButtonAccessible::DoAction(PRUint8 index) { if (index == 0) { - nsCOMPtr buttonElement(do_QueryInterface(mDOMNode)); - if ( buttonElement ) - { - buttonElement->Click(); - return NS_OK; - } - return NS_ERROR_FAILURE; + return DoCommand(); } return NS_ERROR_INVALID_ARG; } @@ -352,12 +346,7 @@ NS_IMETHODIMP nsXULCheckboxAccessible::GetActionName(PRUint8 index, nsAString& _ NS_IMETHODIMP nsXULCheckboxAccessible::DoAction(PRUint8 index) { if (index == eAction_Click) { - nsCOMPtr xulCheckboxElement(do_QueryInterface(mDOMNode)); - if (xulCheckboxElement) { - xulCheckboxElement->Click(); - return NS_OK; - } - return NS_ERROR_FAILURE; + return DoCommand(); } return NS_ERROR_INVALID_ARG; } @@ -483,11 +472,7 @@ nsRadioButtonAccessible(aNode, aShell) NS_IMETHODIMP nsXULRadioButtonAccessible::DoAction(PRUint8 index) { if (index == eAction_Click) { - nsCOMPtr radioButton(do_QueryInterface(mDOMNode)); - if (radioButton) { - radioButton->Click(); - return NS_OK; - } + return DoCommand(); } return NS_ERROR_INVALID_ARG; } diff --git a/accessible/src/xul/nsXULMenuAccessible.cpp b/accessible/src/xul/nsXULMenuAccessible.cpp index dd666eff8379..79d3418fa002 100644 --- a/accessible/src/xul/nsXULMenuAccessible.cpp +++ b/accessible/src/xul/nsXULMenuAccessible.cpp @@ -237,10 +237,7 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetChildCount(PRInt32 *aAccChildCount) NS_IMETHODIMP nsXULMenuitemAccessible::DoAction(PRUint8 index) { if (index == eAction_Select) { // default action - nsCOMPtr xulElement(do_QueryInterface(mDOMNode)); - if (xulElement) - xulElement->Click(); - + DoCommand(); nsCOMPtr parentAccessible; GetParent(getter_AddRefs(parentAccessible)); if (parentAccessible) { diff --git a/accessible/src/xul/nsXULTreeAccessible.cpp b/accessible/src/xul/nsXULTreeAccessible.cpp index 1139c80d081b..fee6467ae318 100644 --- a/accessible/src/xul/nsXULTreeAccessible.cpp +++ b/accessible/src/xul/nsXULTreeAccessible.cpp @@ -911,11 +911,7 @@ NS_IMETHODIMP nsXULTreeColumnitemAccessible::GetActionName(PRUint8 index, nsAStr NS_IMETHODIMP nsXULTreeColumnitemAccessible::DoAction(PRUint8 index) { if (index == eAction_Click) { - nsCOMPtr colElement(do_QueryInterface(mDOMNode)); - if (colElement) - colElement->Click(); - - return NS_OK; + return DoCommand(); } return NS_ERROR_INVALID_ARG;