a (knock on wood) safe fix for (at least) two bugs:

#195011, Dismissing Junk Mail Log dialog crashes Mozilla [@ nsEventListenerManager::HandleEvent]
#137191, Infinite recursion near nsEventStateManager::TabIntoDocument

really the same issue:  guard against tabbing into a sub document, popping back out, and tabbing back in recursively.

r=aaronl, sr=bryner.
This commit is contained in:
sspitzer%netscape.com 2003-03-17 23:08:36 +00:00
Родитель 073c38117d
Коммит 06be46ccb3
2 изменённых файлов: 19 добавлений и 3 удалений

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

@ -177,7 +177,7 @@ nsEventStateManager::nsEventStateManager()
mBrowseWithCaret = PR_FALSE;
mLeftClickOnly = PR_TRUE;
mNormalLMouseEventInProcess = PR_FALSE;
mTabbedThroughDocument = PR_FALSE;
#ifdef CLICK_HOLD_CONTEXT_MENUS
mEventDownWidget = nsnull;
@ -2983,7 +2983,7 @@ nsresult
nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart)
{
#ifdef DEBUG_DOCSHELL_FOCUS
printf("[%p] ShiftFocus: aForward=%d, aStart=%p, mCurrentFocus=%p\n",
printf("[%p] ShiftFocusInternal: aForward=%d, aStart=%p, mCurrentFocus=%p\n",
this, aForward, aStart, mCurrentFocus);
#endif
NS_ASSERTION(mPresContext, "no pres context");
@ -3110,7 +3110,14 @@ nsEventStateManager::ShiftFocusInternal(PRBool aForward, nsIContent* aStart)
presShell->ScrollFrameIntoView(nextFocusFrame,
NS_PRESSHELL_SCROLL_ANYWHERE,
NS_PRESSHELL_SCROLL_ANYWHERE);
TabIntoDocument(sub_shell, aForward);
// if we are in the middle of tabbing into
// sub_shell, bail out, to avoid recursion
// see bug #195011 and bug #137191
if (mTabbingFromDocShells.IndexOf(sub_shell) != -1)
return NS_OK;
TabIntoDocument(sub_shell, aForward);
} else {
// there is no subshell, so just focus nextFocus
#ifdef DEBUG_DOCSHELL_FOCUS
@ -5153,10 +5160,17 @@ nsEventStateManager::TabIntoDocument(nsIDocShell* aDocShell,
nsCOMPtr<nsIEventStateManager> docESM;
pc->GetEventStateManager(getter_AddRefs(docESM));
if (docESM) {
// we are about to shift focus to aDocShell
// keep track of the document, so we don't try to go back into it.
mTabbingFromDocShells.AppendObject(aDocShell);
// clear out any existing focus state
docESM->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
// now focus the first (or last) focusable content
docESM->ShiftFocus(aForward, nsnull);
// remove the document from the list
mTabbingFromDocShells.RemoveObject(aDocShell);
}
}
}

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

@ -48,6 +48,7 @@
#include "nsHashtable.h"
#include "nsITimer.h"
#include "nsIDocument.h"
#include "nsCOMArray.h"
class nsIScrollableView;
class nsIPresShell;
@ -317,6 +318,7 @@ protected:
// Recursion guard for tabbing
PRBool mTabbedThroughDocument;
nsCOMArray<nsIDocShell> mTabbingFromDocShells;
#ifdef CLICK_HOLD_CONTEXT_MENUS
enum { kClickHoldDelay = 500 } ; // 500ms == 1/2 second