- When a docshell first takes focus, give focus to its first focusable content
- Make the docshell come after all of its content in the tabbing order

r=saari, sr=hyatt.
This commit is contained in:
bryner%uiuc.edu 2001-04-18 06:18:10 +00:00
Родитель 9692e7d349
Коммит 120c716a6e
4 изменённых файлов: 115 добавлений и 83 удалений

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

@ -74,6 +74,10 @@ public:
NS_IMETHOD GetFocusedContent(nsIContent **aContent) = 0;
NS_IMETHOD SetFocusedContent(nsIContent* aContent) = 0;
virtual PRBool ChangeFocus(nsIContent* aFocus, nsIFrame* aFocusFrame, PRBool aSetFocus) = 0;
NS_IMETHOD GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame,
PRBool forward, nsIContent** aResult) = 0;
// This is an experiement and may be temporary
NS_IMETHOD ConsumeFocusEvents(PRBool aDoConsume) = 0;

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

@ -2390,12 +2390,26 @@ nsEventStateManager::ShiftFocus(PRBool forward, nsIContent* aRoot)
nsCOMPtr<nsIContent> next;
//Get the next tab item. This takes tabIndex into account
GetNextTabbableContent(rootContent, primaryFrame, forward, getter_AddRefs(next));
if (!topOfDoc)
GetNextTabbableContent(rootContent, primaryFrame, forward, getter_AddRefs(next));
//Either no tabbable items or the end of the document
if (!next) {
PRBool focusTaken = PR_FALSE;
// If we've reached the end of the content in this document, we
// focus the document itself before leaving.
if (!topOfDoc) {
nsCOMPtr<nsIScriptGlobalObject> sgo;
mDocument->GetScriptGlobalObject(getter_AddRefs(sgo));
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(sgo));
if (domwin) {
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
if (NS_SUCCEEDED(domwin->Focus()))
return;
}
}
PRBool focusTaken = PR_FALSE;
SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
//Offer focus upwards to allow shifting focus to UI controls

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

@ -120,8 +120,8 @@ protected:
NS_IMETHOD SetClickCount(nsIPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
NS_IMETHOD CheckForAndDispatchClick(nsIPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus);
PRBool ChangeFocus(nsIContent* aFocus, nsIFrame* aFocusFrame, PRBool aSetFocus);
void ShiftFocus(PRBool foward, nsIContent* aRoot=nsnull);
NS_IMETHOD GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame, PRBool foward, nsIContent** aResult);
void ShiftFocus(PRBool forward, nsIContent* aRoot=nsnull);
NS_IMETHOD GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame, PRBool forward, nsIContent** aResult);
PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward);
NS_IMETHOD SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aContent);
PRBool CheckDisabled(nsIContent* aContent);

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
@ -92,6 +92,8 @@
// http://bugzilla.mozilla.org/show_bug.cgi?id=71482
#include "nsIBrowserHistory.h"
#include "nsIEventStateManager.h"
#ifdef IBMBIDI
#include "nsIUBidiUtils.h"
#endif
@ -1970,96 +1972,108 @@ NS_IMETHODIMP nsDocShell::GetMainWidget(nsIWidget** aMainWidget)
NS_IMETHODIMP nsDocShell::SetFocus()
{
nsCOMPtr<nsIDOMDocument> domDoc;
mContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
if (doc) {
nsCOMPtr<nsIScriptGlobalObject> sgo;
doc->GetScriptGlobalObject(getter_AddRefs(sgo));
if (sgo) {
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(sgo));
if (domwin)
domwin->Focus();
}
nsCOMPtr<nsIPresShell> presShell;
nsCOMPtr<nsIDocument> document;
GetPresShell(getter_AddRefs(presShell));
if (!presShell)
return NS_ERROR_FAILURE;
presShell->GetDocument(getter_AddRefs(document));
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
if (!presContext)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIEventStateManager> esm;
presContext->GetEventStateManager(getter_AddRefs(esm));
if (!esm)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> rootContent(getter_AddRefs(document->GetRootContent()));
if (!rootContent) return NS_ERROR_FAILURE;
nsCOMPtr<nsIContent> focusContent;
esm->GetNextTabbableContent(rootContent, nsnull, PR_TRUE,
getter_AddRefs(focusContent));
if (focusContent) {
nsIFrame* focusFrame = nsnull;
presShell->GetPrimaryFrameFor(focusContent, &focusFrame);
esm->ChangeFocus(focusContent, focusFrame, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP nsDocShell::FocusAvailable(nsIBaseWindow* aCurrentFocus,
PRBool* aTookFocus)
PRBool* aTookFocus)
{
NS_ENSURE_ARG_POINTER(aTookFocus);
NS_ENSURE_ARG_POINTER(aTookFocus);
// Next person we should call is first the parent otherwise the
// docshell tree owner.
// Next person we should call is first the parent otherwise the
// docshell tree owner.
nsCOMPtr<nsIBaseWindow> nextCallWin(do_QueryInterface(mParent));
if(!nextCallWin)
{
nextCallWin = do_QueryInterface(mTreeOwner);
nsCOMPtr<nsIBaseWindow> nextCallWin(do_QueryInterface(mParent));
if(!nextCallWin)
nextCallWin = do_QueryInterface(mTreeOwner);
//If the current focus is us, offer it to the next owner.
if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this)) {
if(nextCallWin) {
nsresult ret = nextCallWin->FocusAvailable(aCurrentFocus, aTookFocus);
if (NS_SUCCEEDED(ret) && *aTookFocus)
return NS_OK;
}
if (!mChildren.Count()) {
//If we don't have children and our parent didn't want
//the focus then we should just stop now.
return NS_OK;
}
}
//Otherwise, check the chilren and offer it to the next sibling.
PRInt32 i;
PRInt32 n = mChildren.Count();
for(i = 0; i < n; i++) {
nsCOMPtr<nsIBaseWindow>
child(do_QueryInterface((nsISupports*)mChildren.ElementAt(i)));
//If we have focus we offer it to our first child.
if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this)) {
if(NS_SUCCEEDED(child->SetFocus())) {
*aTookFocus = PR_TRUE;
return NS_OK;
}
//If the current focus is us, offer it to the next owner.
if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this))
{
if(nextCallWin)
{
nsresult ret = nextCallWin->FocusAvailable(aCurrentFocus, aTookFocus);
if (NS_SUCCEEDED(ret) && *aTookFocus)
else
return NS_ERROR_FAILURE;
}
//If we don't have focus, find the child that does then
//offer focus to the next one.
if (child.get() == aCurrentFocus) {
while(++i < n) {
child = do_QueryInterface((nsISupports*)mChildren.ElementAt(i));
if(NS_SUCCEEDED(child->SetFocus())) {
*aTookFocus = PR_TRUE;
return NS_OK;
}
if (!mChildren.Count())
{
//If we don't have children and our parent didn't want
//the focus then we should just stop now.
return NS_OK;
}
else
return NS_ERROR_FAILURE;
}
}
}
//Reached the end of our child list. If we aren't currently focused, try
// to accept focus.
//Otherwise, check the chilren and offer it to the next sibling.
PRInt32 i;
PRInt32 n = mChildren.Count();
for(i = 0; i < n; i++)
{
nsCOMPtr<nsIBaseWindow>
child(do_QueryInterface((nsISupports*)mChildren.ElementAt(i)));
//If we have focus we offer it to our first child.
if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this))
{
if(NS_SUCCEEDED(child->SetFocus()))
{
*aTookFocus = PR_TRUE;
return NS_OK;
}
else
{
return NS_ERROR_FAILURE;
}
}
//If we don't have focus, find the child that does then
//offer focus to the next one.
if (child.get() == aCurrentFocus)
{
while(++i < n)
{
child = do_QueryInterface((nsISupports*)mChildren.ElementAt(i));
if(NS_SUCCEEDED(child->SetFocus()))
{
*aTookFocus = PR_TRUE;
return NS_OK;
}
else
{
return NS_ERROR_FAILURE;
}
}
}
}
if ((aCurrentFocus != NS_STATIC_CAST(nsIBaseWindow*, this)) &&
NS_SUCCEEDED(SetFocus())) {
*aTookFocus = PR_TRUE;
return NS_OK;
}
//Reached the end of our child list. Call again to offer focus
//upwards and to start at the beginning of our child list if
//no one above us wants focus.
return FocusAvailable(this, aTookFocus);
// Call again to offer focus upwards and to start at the beginning of our
// child list if no one above us wants focus.
return FocusAvailable(this, aTookFocus);
}
NS_IMETHODIMP nsDocShell::GetTitle(PRUnichar** aTitle)