зеркало из https://github.com/mozilla/pjs.git
Bug 291071. Dialog to set Firefox as default browser confused screen reader because of incorrect focus events. r=timeless, sr=neil, a=shaver
This commit is contained in:
Родитель
5f35bd596e
Коммит
1d3788c303
|
@ -189,20 +189,6 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress
|
|||
return NS_OK; // Not interested in frames or iframes, just the root content
|
||||
}
|
||||
|
||||
if (nsAccessNode::gLastFocusedNode) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> focusedDocShellTreeItem =
|
||||
nsAccessNode::GetDocShellTreeItemFor(nsAccessNode::gLastFocusedNode);
|
||||
NS_ENSURE_TRUE(focusedDocShellTreeItem, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIDocShellTreeItem> focusedRootTreeItem;
|
||||
focusedDocShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(focusedRootTreeItem));
|
||||
|
||||
if (focusedRootTreeItem != sameTypeRoot) {
|
||||
// Load is not occuring in the currently focused tab, so don't fire
|
||||
// doc load event there, otherwise assistive technology may become confused
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the accessible for the new document.
|
||||
// If it not created yet this will create it & cache it, as well as
|
||||
// set up event listeners so that MSAA/ATK toolkit and internal
|
||||
|
|
|
@ -121,7 +121,6 @@ class nsDocAccessible : public nsBlockAccessible,
|
|||
nsCOMPtr<nsITimer> mFireEventTimer;
|
||||
nsCOMPtr<nsIEditor> mEditor; // Editor, if there is one
|
||||
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
|
||||
PRPackedBool mIsNewDocument;
|
||||
nsCOMArray<nsIAccessibleEvent> mEventsToFire;
|
||||
};
|
||||
|
||||
|
|
|
@ -232,9 +232,6 @@ nsresult nsRootAccessible::AddEventListeners()
|
|||
nsresult rv = target->AddEventListener(NS_LITERAL_STRING("focus"), NS_STATIC_CAST(nsIDOMFocusListener*, this), PR_TRUE);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register listener");
|
||||
|
||||
// Fire accessible focus event for pre-existing focus
|
||||
FireCurrentFocusEvent();
|
||||
|
||||
// capture Form change events
|
||||
rv = target->AddEventListener(NS_LITERAL_STRING("select"), NS_STATIC_CAST(nsIDOMFormListener*, this), PR_TRUE);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to register listener");
|
||||
|
@ -293,6 +290,14 @@ nsresult nsRootAccessible::AddEventListeners()
|
|||
if (!mCaretAccessible)
|
||||
mCaretAccessible = new nsCaretAccessible(mDOMNode, mWeakShell, this);
|
||||
|
||||
// Fire accessible focus event for pre-existing focus, but wait until all internal
|
||||
// focus events are finished for window initialization.
|
||||
mFireFocusTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mFireFocusTimer) {
|
||||
mFireFocusTimer->InitWithFuncCallback(FireFocusCallback, this,
|
||||
0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
return nsDocAccessible::AddEventListeners();
|
||||
}
|
||||
|
||||
|
@ -863,6 +868,13 @@ void nsRootAccessible::GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNo
|
|||
}
|
||||
}
|
||||
|
||||
void nsRootAccessible::FireFocusCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsRootAccessible *rootAccessible = NS_STATIC_CAST(nsRootAccessible*, aClosure);
|
||||
NS_ASSERTION(rootAccessible, "How did we get here without a root accessible?");
|
||||
rootAccessible->FireCurrentFocusEvent();
|
||||
}
|
||||
|
||||
// ------- nsIDOMFocusListener Methods (1) -------------
|
||||
|
||||
NS_IMETHODIMP nsRootAccessible::Focus(nsIDOMEvent* aEvent)
|
||||
|
@ -936,6 +948,10 @@ NS_IMETHODIMP nsRootAccessible::Shutdown()
|
|||
mMenuAccessible = nsnull;
|
||||
mCaretAccessible = nsnull;
|
||||
mAccService = nsnull;
|
||||
if (mFireEventTimer) {
|
||||
mFireFocusTimer->Cancel();
|
||||
mFireFocusTimer = nsnull;
|
||||
}
|
||||
|
||||
return nsDocAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMXULListener.h"
|
||||
#include "nsIAccessibleCaret.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
class nsIAccessibleEventListener;
|
||||
|
||||
|
@ -100,6 +101,10 @@ class nsRootAccessible : public nsDocAccessibleWrap,
|
|||
|
||||
void ShutdownAll();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsITimer> mFireFocusTimer;
|
||||
static void FireFocusCallback(nsITimer *aTimer, void *aClosure);
|
||||
|
||||
protected:
|
||||
nsresult AddEventListeners();
|
||||
nsresult RemoveEventListeners();
|
||||
|
|
|
@ -345,14 +345,31 @@ void nsDocAccessibleWrap::DocLoadCallback(nsITimer *aTimer, void *aClosure)
|
|||
// Doc has finished loading, fire "load finished" event
|
||||
// By using short timer we can wait for MS Windows to make the window visible,
|
||||
// which it does asynchronously. This avoids confusing the screen reader with a
|
||||
// hidden window.
|
||||
// hidden window. Waiting also allows us to see of the document has focus,
|
||||
// which is important because we only fire doc loaded events for focused documents.
|
||||
|
||||
nsDocAccessibleWrap *docAcc =
|
||||
NS_REINTERPRET_CAST(nsDocAccessibleWrap*, aClosure);
|
||||
if (docAcc) {
|
||||
docAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE,
|
||||
docAcc, nsnull);
|
||||
docAcc->FireAnchorJumpEvent();
|
||||
if (!docAcc) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fire doc finished event
|
||||
nsCOMPtr<nsIDOMNode> docDomNode;
|
||||
docAcc->GetDOMNode(getter_AddRefs(docDomNode));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(docDomNode));
|
||||
if (doc) {
|
||||
nsCOMPtr<nsISupports> container = doc->GetContainer();
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
if (docShell) {
|
||||
PRBool hasFocus;
|
||||
docShell->GetHasFocus(&hasFocus);
|
||||
if (hasFocus) {
|
||||
docAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE,
|
||||
docAcc, nsnull);
|
||||
docAcc->FireAnchorJumpEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче