Bug 110718. During the 'transferring' when the currently visible document is a zombie, the keyboard is dead for the entire document. r=bryner, sr=hyatt+scc

git-svn-id: svn://10.0.0.236/trunk@135298 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
aaronl%netscape.com
2002-12-14 08:05:51 +00:00
parent 780fef7a28
commit ed5fb21283
4 changed files with 161 additions and 11 deletions

View File

@@ -3620,12 +3620,32 @@ nsEventStateManager::GetNextTabbableContent(nsIContent* aRootContent, nsIFrame*
disabled = PR_FALSE;
}
}
else if (nsHTMLAtoms::iframe==tag) {
disabled = PR_FALSE;
else if (nsHTMLAtoms::iframe==tag || nsHTMLAtoms::frame==tag) {
disabled = PR_TRUE;
if (child) {
nsCOMPtr<nsIDocument> doc, subDoc;
child->GetDocument(*getter_AddRefs(doc));
if (doc) {
doc->GetSubDocumentFor(child, getter_AddRefs(subDoc));
nsCOMPtr<nsISupports> container;
subDoc->GetContainer(getter_AddRefs(container));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
if (docShell) {
nsCOMPtr<nsIContentViewer> contentViewer, zombieViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));
if (contentViewer) {
contentViewer->GetPreviousViewer(getter_AddRefs(zombieViewer));
if (!zombieViewer) {
// If there are 2 viewers for the current docshell, that
// means the current document is a zombie document.
// Only navigate into the frame/iframe if it's not a zombie
disabled = PR_FALSE;
}
}
}
}
}
}
else if (nsHTMLAtoms::frame==tag) {
disabled = PR_FALSE;
}
}
// Check the tabindex attribute, unless the model specifies text only.
// If the model is unset then we'll depend on tabindex.
@@ -4684,7 +4704,11 @@ void nsEventStateManager::FocusElementButNotDocument(nsIContent *aContent)
{
// Focus an element in the current document, but don't switch document/window focus!
if (gLastFocusedDocument == mDocument) { // If we're already in this document, use normal focus method
if (gLastFocusedDocument == mDocument ||
!gLastFocusedContent) {
// If we're already focused in this document,
// or if there was no last focus
// use normal focus method
if (mCurrentFocus != aContent) {
if (aContent)
aContent->SetFocus(mPresContext);
@@ -4693,7 +4717,8 @@ void nsEventStateManager::FocusElementButNotDocument(nsIContent *aContent)
}
return;
}
// The last focus wasn't in this document, so we may be getting our postion from the selection
// The last focus wasn't in this document, so we may be getting our position from the selection
// while the window focus is currently somewhere else such as the find dialog
// Temporarily save the current focus globals so we can leave them undisturbed after this method

View File

@@ -117,6 +117,7 @@
#include "nsIExternalProtocolService.h"
#include "nsIFocusController.h"
#include "nsIEventStateManager.h"
#include "nsITextToSubURI.h"
@@ -4614,6 +4615,22 @@ nsDocShell::SetupNewViewer(nsIContentViewer * aNewViewer)
}
}
// Eliminate the focus ring in the current docshell, which is
// now a zombie. If we key navigate, it won't be within this
// docshell, until the newly loading document is displayed.
if (mItemType == typeContent) {
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
if (presContext) {
nsCOMPtr<nsIEventStateManager> esm;
presContext->GetEventStateManager(getter_AddRefs(esm));
if (esm) {
esm->SetFocusedContent(nsnull);
esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
}
}
}
// It is necessary to obtain the focus controller to utilize its ability
// to suppress focus. This is necessary to fix Win32-only bugs related to
// a loss of focus when mContentViewer is set to null. The internal window

View File

@@ -1360,6 +1360,11 @@ protected:
private:
PRBool InZombieDocument(nsIContent *aContent);
nsresult RetargetEventToParent(nsIView *aView, nsGUIEvent* aEvent,
nsEventStatus* aEventStatus, PRBool aForceHandle,
PRBool& aHandled);
void FreeDynamicStack();
//helper funcs for disabing autoscrolling
@@ -5864,6 +5869,52 @@ PresShell::PopCurrentEventInfo()
}
}
PRBool PresShell::InZombieDocument(nsIContent *aContent)
{
// If a content node points to a null document, it is a
// zombie document, about to be replaced by a newly loading document.
// Such documents cannot handle DOM events.
nsCOMPtr<nsIDocument> doc;
mCurrentEventContent->GetDocument(*getter_AddRefs(doc));
return !doc;
}
nsresult PresShell::RetargetEventToParent(nsIView *aView,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus,
PRBool aForceHandle,
PRBool& aHandled)
{
// Sent this events straight up to the parent pres shell.
// We do this for non-mouse events in zombie documents.
// That way at least the UI key bindings can work.
nsCOMPtr<nsISupports> container;
mPresContext->GetContainer(getter_AddRefs(container));
nsCOMPtr<nsIDocShellTreeItem> treeItem =
do_QueryInterface(container);
if (treeItem) {
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
treeItem->GetParent(getter_AddRefs(parentTreeItem));
nsCOMPtr<nsIDocShell> parentDocShell =
do_QueryInterface(parentTreeItem);
if (parentDocShell && treeItem != parentTreeItem) {
nsCOMPtr<nsIPresShell> parentPresShell;
parentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
nsCOMPtr<nsIViewObserver> parentViewObserver =
do_QueryInterface(parentPresShell);
if (parentViewObserver) {
PopCurrentEventInfo();
return parentViewObserver->HandleEvent(aView, aEvent,
aEventStatus,
aForceHandle,
aHandled);
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
PresShell::HandleEvent(nsIView *aView,
nsGUIEvent* aEvent,
@@ -5942,8 +5993,7 @@ PresShell::HandleEvent(nsIView *aView,
if (mSelectionFlags && NS_SUCCEEDED(mSelection->HandleKeyEvent(mPresContext, aEvent)))
{
return NS_OK;
}
}
} }
*/
if (nsnull != frame) {
PushCurrentEventInfo(nsnull, nsnull);
@@ -5996,6 +6046,10 @@ PresShell::HandleEvent(nsIView *aView,
#endif /* defined(MOZ_X11) */
mCurrentEventFrame = nsnull;
}
if (mCurrentEventContent && InZombieDocument(mCurrentEventContent)) {
return RetargetEventToParent(aView, aEvent, aEventStatus,
aForceHandle, aHandled);
}
}
else if (!InClipRect(frame, aEvent->point)) {
// we only check for the clip rect on this frame ... all frames with clip have views so any

View File

@@ -1360,6 +1360,11 @@ protected:
private:
PRBool InZombieDocument(nsIContent *aContent);
nsresult RetargetEventToParent(nsIView *aView, nsGUIEvent* aEvent,
nsEventStatus* aEventStatus, PRBool aForceHandle,
PRBool& aHandled);
void FreeDynamicStack();
//helper funcs for disabing autoscrolling
@@ -5864,6 +5869,52 @@ PresShell::PopCurrentEventInfo()
}
}
PRBool PresShell::InZombieDocument(nsIContent *aContent)
{
// If a content node points to a null document, it is a
// zombie document, about to be replaced by a newly loading document.
// Such documents cannot handle DOM events.
nsCOMPtr<nsIDocument> doc;
mCurrentEventContent->GetDocument(*getter_AddRefs(doc));
return !doc;
}
nsresult PresShell::RetargetEventToParent(nsIView *aView,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus,
PRBool aForceHandle,
PRBool& aHandled)
{
// Sent this events straight up to the parent pres shell.
// We do this for non-mouse events in zombie documents.
// That way at least the UI key bindings can work.
nsCOMPtr<nsISupports> container;
mPresContext->GetContainer(getter_AddRefs(container));
nsCOMPtr<nsIDocShellTreeItem> treeItem =
do_QueryInterface(container);
if (treeItem) {
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
treeItem->GetParent(getter_AddRefs(parentTreeItem));
nsCOMPtr<nsIDocShell> parentDocShell =
do_QueryInterface(parentTreeItem);
if (parentDocShell && treeItem != parentTreeItem) {
nsCOMPtr<nsIPresShell> parentPresShell;
parentDocShell->GetPresShell(getter_AddRefs(parentPresShell));
nsCOMPtr<nsIViewObserver> parentViewObserver =
do_QueryInterface(parentPresShell);
if (parentViewObserver) {
PopCurrentEventInfo();
return parentViewObserver->HandleEvent(aView, aEvent,
aEventStatus,
aForceHandle,
aHandled);
}
}
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
PresShell::HandleEvent(nsIView *aView,
nsGUIEvent* aEvent,
@@ -5942,8 +5993,7 @@ PresShell::HandleEvent(nsIView *aView,
if (mSelectionFlags && NS_SUCCEEDED(mSelection->HandleKeyEvent(mPresContext, aEvent)))
{
return NS_OK;
}
}
} }
*/
if (nsnull != frame) {
PushCurrentEventInfo(nsnull, nsnull);
@@ -5996,6 +6046,10 @@ PresShell::HandleEvent(nsIView *aView,
#endif /* defined(MOZ_X11) */
mCurrentEventFrame = nsnull;
}
if (mCurrentEventContent && InZombieDocument(mCurrentEventContent)) {
return RetargetEventToParent(aView, aEvent, aEventStatus,
aForceHandle, aHandled);
}
}
else if (!InClipRect(frame, aEvent->point)) {
// we only check for the clip rect on this frame ... all frames with clip have views so any