Backporting fixes for bugs 104977 (tabbing rewrite), and 81398 (tabbing through out-of-flow frames) to the branch to fix bug 91184. r=saari, sr=hyatt, a=marek.
git-svn-id: svn://10.0.0.236/branches/MOZILLA_0_9_4_BRANCH@109246 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -33,7 +33,6 @@ class nsIDOMEvent;
|
||||
class nsIFrame;
|
||||
class nsIView;
|
||||
class nsIWidget;
|
||||
class nsIDocument;
|
||||
|
||||
/*
|
||||
* Event listener manager interface.
|
||||
@@ -75,19 +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;
|
||||
|
||||
NS_IMETHOD GetNextTabbableIndexContent(nsIContent* aRootContent,
|
||||
PRBool forward,
|
||||
PRBool aStartOver,
|
||||
nsIContent** aResult) = 0;
|
||||
|
||||
NS_IMETHOD HasPositiveTabIndex(nsIContent* aContent,
|
||||
PRBool* aResult) = 0;
|
||||
|
||||
// This is an experiement and may be temporary
|
||||
// This is an experiment and may be temporary
|
||||
NS_IMETHOD ConsumeFocusEvents(PRBool aDoConsume) = 0;
|
||||
|
||||
// Access Key Registration
|
||||
@@ -100,11 +90,7 @@ public:
|
||||
NS_IMETHOD DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent) = 0;
|
||||
|
||||
// Method for moving the focus forward/back.
|
||||
NS_IMETHOD MoveFocus(PRBool aDirection, nsIContent* aRoot)=0;
|
||||
|
||||
//-- Special Enums needed for DocShell Identification
|
||||
enum eDocType {eChrome = 0, eGenericContent, eFrameSet, eFrame, eIFrame};
|
||||
NS_IMETHOD FigureOutKindOfDoc(nsIDocument* aDoc, eDocType* aDocType) = 0;
|
||||
NS_IMETHOD ShiftFocus(PRBool aDirection, nsIContent* aStart)=0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,8 @@ class nsIPresShell;
|
||||
class nsITreeFrame;
|
||||
class nsIFrameSelection;
|
||||
class nsIDocShell;
|
||||
class nsIDocShellTreeNode;
|
||||
class nsIDocShellTreeItem;
|
||||
|
||||
// mac uses click-hold context menus, a holdover from 4.x
|
||||
#ifdef XP_MAC
|
||||
@@ -112,9 +114,7 @@ public:
|
||||
//Method for centralized distribution of new DOM events
|
||||
NS_IMETHOD DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent);
|
||||
|
||||
NS_IMETHOD MoveFocus(PRBool aDirection, nsIContent* aRoot);
|
||||
|
||||
NS_IMETHOD FigureOutKindOfDoc(nsIDocument* aDoc, eDocType* aDocType);
|
||||
NS_IMETHOD ShiftFocus(PRBool forward, nsIContent* aStart=nsnull);
|
||||
|
||||
protected:
|
||||
void UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
|
||||
@@ -122,15 +122,8 @@ protected:
|
||||
void GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent);
|
||||
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 forward, nsIContent* aRoot=nsnull);
|
||||
PRBool ChangeFocus(nsIContent* aFocus);
|
||||
NS_IMETHOD GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame, PRBool forward, nsIContent** aResult);
|
||||
NS_IMETHOD GetNextTabbableIndexContent(nsIContent* aRootContent,
|
||||
PRBool forward,
|
||||
PRBool aStartOver,
|
||||
nsIContent** aResult);
|
||||
NS_IMETHOD HasPositiveTabIndex(nsIContent* aContent,
|
||||
PRBool* aResult);
|
||||
|
||||
PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward);
|
||||
NS_IMETHOD SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aContent);
|
||||
@@ -143,21 +136,17 @@ protected:
|
||||
// DocShell Focus Traversal Methods
|
||||
//---------------------------------------------
|
||||
|
||||
void ShiftFocusByDoc(PRBool forward, nsIContent* aRoot=nsnull);
|
||||
PRBool FocusAfterHTMLFrameDoc(nsIDocShell* aDocShell, nsIDocShell* aParentDocShell, PRBool aForward);
|
||||
PRBool FocusAfterHTMLIFrameDoc(nsIDocShell* aDocShell, nsIDocShell* aParentDocShell, PRBool aForward, PRBool& aFocusDoc);
|
||||
PRBool FocusWithinHTMLFrameDoc(nsIContent* aRootContent, nsIPresShell* aPresShell, PRBool aForward, PRBool& aDoFocusAvailDocShells);
|
||||
PRBool FocusWithinHTMLIFrameDoc(nsIContent* aNextContent, PRBool aForward);
|
||||
nsIContent* GetLastContent(nsIDocShell* aDocShell);
|
||||
nsIContent* GetLastContent(nsIContent* aRootContent);
|
||||
nsIDocShell* GetDocShellFromContent(nsIDocShell* aParentDocShell, nsIContent* aContent);
|
||||
nsIDocShell* GetNextDocShell(nsIDocShell* aParentDS, nsIDocShell* aCurrentDS, PRBool aForward);
|
||||
void ForceUpdate(nsIDocShell* aDocShell);
|
||||
nsresult GetDocShellsFromDoc(nsIDocument* aDocument, nsIDocShell** aDocShell, nsIDocShell** aParentDS);
|
||||
PRBool IsLastFrameInFrameSet(nsIContent* aLastFrameContent);
|
||||
nsIContent* FindContentForDocShell(nsIPresShell* aPresShell, nsIContent* aContent, nsIDocShell* aDocShell);
|
||||
PRBool IsFrameSetDoc(nsIContent* aContent);
|
||||
|
||||
void TabIntoDocument(nsIDocShell* aDocShell, PRBool aForward);
|
||||
void ShiftFocusByDoc(PRBool forward);
|
||||
PRBool IsFrameSetDoc(nsIDocShell* aDocShell);
|
||||
PRBool IsIFrameDoc(nsIDocShell* aDocShell);
|
||||
PRBool IsShellVisible(nsIDocShell* aShell);
|
||||
void GetLastChildDocShell(nsIDocShellTreeItem* aItem,
|
||||
nsIDocShellTreeItem** aResult);
|
||||
void GetNextDocShell(nsIDocShellTreeNode* aNode,
|
||||
nsIDocShellTreeItem** aResult);
|
||||
void GetPrevDocShell(nsIDocShellTreeNode* aNode,
|
||||
nsIDocShellTreeItem** aResult);
|
||||
|
||||
// These functions are for mousewheel scrolling
|
||||
nsIScrollableView* GetNearestScrollingView(nsIView* aView);
|
||||
@@ -239,7 +228,7 @@ protected:
|
||||
|
||||
static PRUint32 mInstanceCount;
|
||||
|
||||
// For mousewheel preferences handling
|
||||
// For preferences handling
|
||||
nsCOMPtr<nsIPref> mPrefService;
|
||||
PRBool m_haveShutdown;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ static NS_DEFINE_CID(kPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
|
||||
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
|
||||
#ifdef DEBUG_rods
|
||||
#if defined(DEBUG_rods) || defined(DEBUG_bryner)
|
||||
//#define DEBUG_DOCSHELL_FOCUS
|
||||
#endif
|
||||
//
|
||||
@@ -1261,22 +1261,6 @@ NS_IMETHODIMP nsDocShell::SetAllowImages(PRBool aAllowImages)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetFocusDocBeforeContent(PRBool* aDocFirst)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDocFirst);
|
||||
|
||||
*aDocFirst = mFocusDocFirst;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetFocusDocBeforeContent(PRBool aDocFirst)
|
||||
{
|
||||
mFocusDocFirst = aDocFirst;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetDocShellEnumerator(PRInt32 aItemType, PRInt32 aDirection, nsISimpleEnumerator **outEnum)
|
||||
{
|
||||
@@ -1405,6 +1389,24 @@ nsDocShell::GetBusyFlags(PRUint32 * aBusyFlags)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::TabToTreeOwner(PRBool aForward, PRBool* aTookFocus)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTookFocus);
|
||||
|
||||
nsCOMPtr<nsIWebBrowserChromeFocus> chromeFocus = do_GetInterface(mTreeOwner);
|
||||
if (chromeFocus) {
|
||||
if (aForward)
|
||||
*aTookFocus = NS_SUCCEEDED(chromeFocus->FocusNextElement());
|
||||
else
|
||||
*aTookFocus = NS_SUCCEEDED(chromeFocus->FocusPrevElement());
|
||||
} else
|
||||
*aTookFocus = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShell::nsIDocShellTreeItem
|
||||
//*****************************************************************************
|
||||
@@ -2680,7 +2682,7 @@ nsDocShell::GetVisibility(PRBool * aVisibility)
|
||||
|
||||
// convert the view's visibility attribute to a bool
|
||||
nsViewVisibility vis;
|
||||
NS_ENSURE_TRUE(rootView->GetVisibility(vis), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_SUCCESS(rootView->GetVisibility(vis), NS_ERROR_FAILURE);
|
||||
*aVisibility = nsViewVisibility_kHide == vis ? PR_FALSE : PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
@@ -2708,28 +2710,6 @@ nsDocShell::GetMainWidget(nsIWidget ** aMainWidget)
|
||||
return GetParentWidget(aMainWidget);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::ForceUpdate(nsIDocShell* aDocShell)
|
||||
{
|
||||
NS_ASSERTION(aDocShell, "DocShell is null!");
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aDocShell->GetPresShell(getter_AddRefs(presShell));
|
||||
|
||||
// we might not have a presshell yet
|
||||
if (!presShell)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
presShell->GetViewManager(getter_AddRefs(vm));
|
||||
if (vm) {
|
||||
vm->UpdateAllViews(NS_VMREFRESH_NO_SYNC);
|
||||
#ifdef DEBUG_DOCSHELL_FOCUS
|
||||
printf("nsDocShell::ForceUpdate - DS: %p **********\n", aDocShell);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetFocus()
|
||||
{
|
||||
@@ -2737,349 +2717,14 @@ nsDocShell::SetFocus()
|
||||
printf("nsDocShell::SetFocus %p\n", (nsIDocShell*)this);
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
GetPresShell(getter_AddRefs(presShell));
|
||||
if (!presShell)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
/* Check to make sure the root frame for this document
|
||||
is not collapsed. */
|
||||
nsIFrame* rootFrame;
|
||||
presShell->GetRootFrame(&rootFrame);
|
||||
if (rootFrame) {
|
||||
nsRect frameRect;
|
||||
rootFrame->GetRect(frameRect);
|
||||
if (frameRect.IsEmpty()) {
|
||||
#ifdef DEBUG_bryner
|
||||
printf("SetFocus: empty frame rect, not accepting focus\n");
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
presShell->GetDocument(getter_AddRefs(document));
|
||||
|
||||
// Figure out what type of document this is
|
||||
// if parent doc is content then set focus to document itself
|
||||
// and set the "special" flag so it knows we are at the beginning
|
||||
// of the document
|
||||
PRBool doFocusDoc = PR_FALSE;
|
||||
nsIDocShellTreeItem* treeItem = NS_STATIC_CAST(nsIDocShellTreeItem *, this);
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
||||
treeItem->GetParent(getter_AddRefs(parentItem));
|
||||
if (parentItem) {
|
||||
PRInt32 type;
|
||||
parentItem->GetItemType(&type);
|
||||
doFocusDoc = type == nsIDocShellTreeItem::typeContent;
|
||||
}
|
||||
|
||||
if (mFocusDocFirst)
|
||||
doFocusDoc = PR_TRUE;
|
||||
|
||||
// Tell itself (and the DocShellFocusController) who has focus
|
||||
// this way focus gets removed from the currently focused DocShell
|
||||
|
||||
SetHasFocus(PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIContent> focusContent;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
GetPresContext(getter_AddRefs(presContext));
|
||||
if (presContext) {
|
||||
presContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
nsCOMPtr<nsIContent> rootContent;
|
||||
document->GetRootContent(getter_AddRefs(rootContent));
|
||||
if (esm && rootContent) {
|
||||
// Either focus the document or the "first" piece of content
|
||||
if (doFocusDoc) {
|
||||
esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> content;
|
||||
esm->GetNextTabbableIndexContent(rootContent, PR_TRUE, PR_TRUE, getter_AddRefs(content));
|
||||
if (!content) {
|
||||
esm->GetNextTabbableContent(rootContent, nsnull, PR_TRUE,
|
||||
getter_AddRefs(focusContent));
|
||||
} else {
|
||||
focusContent = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (focusContent) {
|
||||
nsIFrame *focusFrame = nsnull;
|
||||
presShell->GetPrimaryFrameFor(focusContent, &focusFrame);
|
||||
esm->ChangeFocus(focusContent, focusFrame, PR_TRUE);
|
||||
SetCanvasHasFocus(PR_FALSE);
|
||||
} else {
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo;
|
||||
document->GetScriptGlobalObject(getter_AddRefs(sgo));
|
||||
if (sgo) {
|
||||
nsCOMPtr<nsIDOMWindowInternal> domwin(do_QueryInterface(sgo));
|
||||
if (domwin)
|
||||
domwin->Focus();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Finds the very next DocShell after the arg aNode
|
||||
nsresult
|
||||
nsDocShell::FindNextChildDoc(nsIDocShellTreeNode* aNode, PRBool aForward, nsIDocShell** aDocShell)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
*aDocShell = nsnull;
|
||||
|
||||
PRInt32 count;
|
||||
aNode->GetChildCount(&count);
|
||||
if (count > 0) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> child;
|
||||
aNode->GetChildAt(aForward?0:count-1, getter_AddRefs(child));
|
||||
NS_ASSERTION(child, "Child can't be null!");
|
||||
nsCOMPtr<nsIDocShell>ds = do_QueryInterface(child);
|
||||
*aDocShell = ds.get();
|
||||
NS_ADDREF(*aDocShell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// Finds the very next DocShell after the arg aNode
|
||||
PRBool
|
||||
nsDocShell::FocusNextChild(nsIBaseWindow * aCurrentFocus, PRBool aForward)
|
||||
{
|
||||
// Make sure the current focused item is content
|
||||
// and if so find the next content DS and give it focus
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(aCurrentFocus));
|
||||
if (treeItem) {
|
||||
PRInt32 type;
|
||||
treeItem->GetItemType(&type);
|
||||
if (type == nsIDocShellTreeItem::typeContent) {
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aCurrentFocus));
|
||||
if (!docShell) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aCurrentFocus));
|
||||
if (!treeNode) return PR_FALSE;
|
||||
PRInt32 childCount;
|
||||
treeNode->GetChildCount(&childCount);
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
docShell->GetPresContext(getter_AddRefs(presContext));
|
||||
if (!presContext) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
presContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
if (!esm) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
docShell->GetPresShell(getter_AddRefs(presShell));
|
||||
if (!presShell) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
presShell->GetDocument(getter_AddRefs(document));
|
||||
if (!document) return PR_FALSE;
|
||||
|
||||
nsIEventStateManager::eDocType docType;
|
||||
if (NS_FAILED(esm->FigureOutKindOfDoc(document, &docType))) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIContent> rootContent;
|
||||
document->GetRootContent(getter_AddRefs(rootContent));
|
||||
if (!rootContent) return PR_FALSE;
|
||||
|
||||
PRBool hasTabIndexes;
|
||||
esm->HasPositiveTabIndex(rootContent, &hasTabIndexes); // ignoring return code
|
||||
|
||||
nsIDocShell* thisDS = NS_STATIC_CAST(nsIDocShell *, this);
|
||||
// leave printf for debugging
|
||||
//printf("DS: %p TBI: %s chld: %s DSE: %s\n", docShell.get(), hasTabIndexes?"Y":"N", childCount > 0?"Y":"N", docShell.get() != thisDS?"Y":"N");
|
||||
if (docType == nsIEventStateManager::eFrameSet ||
|
||||
(docShell.get() != thisDS && !hasTabIndexes && childCount > 0)) {
|
||||
nsCOMPtr<nsIDocShell> childDS;
|
||||
if (NS_SUCCEEDED(FindNextChildDoc(treeNode, aForward, getter_AddRefs(childDS)))) {
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(childDS));
|
||||
if (NS_SUCCEEDED(baseWin->SetFocus())) {
|
||||
MakeSureOfSetFocus(baseWin);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
} else if (docShell.get() != thisDS) {
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(docShell));
|
||||
if (NS_SUCCEEDED(baseWin->SetFocus())) {
|
||||
MakeSureOfSetFocus(baseWin);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// This is just in case we run into a window that
|
||||
// isn't implemented nsDocShell, because if it is implemented
|
||||
// by this class then all this will have already been done.
|
||||
void
|
||||
nsDocShell::MakeSureOfSetFocus(nsIBaseWindow * aCurrentFocus, nsIDocShell* aDocShell)
|
||||
{
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aCurrentFocus);
|
||||
if (!docShell) {
|
||||
if (aDocShell != nsnull) {
|
||||
docShell = aDocShell;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool hasFocus;
|
||||
docShell->GetHasFocus(&hasFocus);
|
||||
|
||||
// leave printf for debugging purposes
|
||||
//printf(">>>>>>>>>> nsDocShell::SetHasFocus: %p %s\n", docShell.get(), hasFocus?"Yes":"No");
|
||||
|
||||
if (!hasFocus) {
|
||||
docShell->SetHasFocus(PR_TRUE);
|
||||
|
||||
nsDocShellFocusController* dsfc = nsDocShellFocusController::GetInstance();
|
||||
if (dsfc) {
|
||||
dsfc->Focus(docShell);
|
||||
}
|
||||
ForceUpdate(docShell);// Force Paint Here
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::FocusAvailable(nsIBaseWindow * aCurrentFocus,
|
||||
PRBool aForward, PRBool * aTookFocus)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTookFocus);
|
||||
|
||||
nsresult ret;
|
||||
|
||||
// Are we embedded?
|
||||
|
||||
nsCOMPtr<nsIWebBrowserChromeFocus>
|
||||
chromeFocus(do_GetInterface(mTreeOwner, &ret));
|
||||
if (chromeFocus) {
|
||||
#ifdef DEBUG_dr
|
||||
printf("dr :: nsDocShell::FocusAvailable, embedded\n");
|
||||
#endif
|
||||
if (aForward)
|
||||
ret = chromeFocus->FocusNextElement();
|
||||
else
|
||||
ret = chromeFocus->FocusPrevElement();
|
||||
|
||||
if (NS_SUCCEEDED(ret)) {
|
||||
// For DocShell's not implemented by this class
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(chromeFocus));
|
||||
MakeSureOfSetFocus(nsnull, docShell);
|
||||
*aTookFocus = PR_TRUE;
|
||||
return ret;
|
||||
} else {
|
||||
// If the embeddor does not implement FocusNext/PrevElement,
|
||||
// or some other error occurred, just focus ourselves again.
|
||||
SetFocus();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DOCSHELL_FOCUS
|
||||
nsIDocShellTreeNode* node = NS_STATIC_CAST(nsIDocShellTreeNode *, this);
|
||||
if (node) {
|
||||
PrintDocTree(node);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Otherwise, first person we should call is the parent, or the
|
||||
// docshell tree owner.
|
||||
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) {
|
||||
|
||||
// Make sure the current focused item is content
|
||||
// and if so find the next content DS and give it focus
|
||||
if (FocusNextChild(aCurrentFocus, aForward)) {
|
||||
*aTookFocus = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ret = nextCallWin->FocusAvailable(aCurrentFocus,
|
||||
aForward, 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 take focus again.
|
||||
SetFocus();
|
||||
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)) {
|
||||
// Make sure the current focused item is content
|
||||
// and if so find the next content DS and give it focus
|
||||
if (FocusNextChild(child, aForward)) {
|
||||
*aTookFocus = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(child->SetFocus())) {
|
||||
*aTookFocus = PR_TRUE;
|
||||
// For DocShell's not implemented by this class
|
||||
MakeSureOfSetFocus(child);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
//If we don't have focus, find the child that does then
|
||||
//offer focus to the next one.
|
||||
else if (child.get() == aCurrentFocus) {
|
||||
while (++i < n) {
|
||||
child =
|
||||
do_QueryInterface((nsISupports *) mChildren.ElementAt(i));
|
||||
if (NS_SUCCEEDED(child->SetFocus())) {
|
||||
*aTookFocus = PR_TRUE;
|
||||
// For DocShell's not implemented by this class
|
||||
MakeSureOfSetFocus(child);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Reached the end of our child list. If we aren't currently focused, try
|
||||
// to accept focus.
|
||||
|
||||
if ((aCurrentFocus != NS_STATIC_CAST(nsIBaseWindow *, this)) &&
|
||||
NS_SUCCEEDED(SetFocus())) {
|
||||
*aTookFocus = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// 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, aForward, aTookFocus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetTitle(PRUnichar ** aTitle)
|
||||
{
|
||||
@@ -6018,16 +5663,9 @@ nsDocShell::GetHasFocus(PRBool *aHasFocus)
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetHasFocus(PRBool aHasFocus)
|
||||
{
|
||||
if (mParent != nsnull) {
|
||||
PRInt32 type;
|
||||
mParent->GetItemType(&type);
|
||||
if (type != nsIDocShellTreeItem::typeContent) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// leave printf for debgging purposes
|
||||
//printf(">>>>>>>>>> nsDocShell::SetHasFocus: %p %s\n", this, aHasFocus?"Yes":"No");
|
||||
#ifdef DEBUG_DOCSHELL_FOCUS
|
||||
printf(">>>>>>>>>> nsDocShell::SetHasFocus: %p %s\n", this, aHasFocus?"Yes":"No");
|
||||
#endif
|
||||
|
||||
mHasFocus = aHasFocus;
|
||||
|
||||
@@ -6036,10 +5674,14 @@ nsDocShell::SetHasFocus(PRBool aHasFocus)
|
||||
dsfc->Focus(this);
|
||||
}
|
||||
|
||||
SetCanvasHasFocus(aHasFocus);
|
||||
if (!aHasFocus) {
|
||||
// We may be in a situation where the focus outline was shown
|
||||
// on this document because the user tabbed into it, but the focus
|
||||
// is now switching to another document via a click. In this case,
|
||||
// we need to make sure the focus outline is removed from this document.
|
||||
SetCanvasHasFocus(PR_FALSE);
|
||||
}
|
||||
|
||||
// Force Paint Here
|
||||
ForceUpdate(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -6068,6 +5710,17 @@ nsDocShell::SetCanvasHasFocus(PRBool aCanvasHasFocus)
|
||||
nsICanvasFrame* canvasFrame;
|
||||
if (NS_SUCCEEDED(frame->QueryInterface(NS_GET_IID(nsICanvasFrame), (void**)&canvasFrame))) {
|
||||
canvasFrame->SetHasFocus(aCanvasHasFocus);
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
GetPresContext(getter_AddRefs(presContext));
|
||||
|
||||
nsIView* canvasView = nsnull;
|
||||
frame->GetView(presContext, &canvasView);
|
||||
|
||||
nsCOMPtr<nsIViewManager> viewManager;
|
||||
canvasView->GetViewManager(*getter_AddRefs(viewManager));
|
||||
viewManager->UpdateView(canvasView, NS_VMREFRESH_NO_SYNC);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,12 +266,6 @@ protected:
|
||||
|
||||
PRBool IsFrame();
|
||||
|
||||
// DocShell Focus helpers
|
||||
void ForceUpdate(nsIDocShell* aDocShell);
|
||||
nsresult FindNextChildDoc(nsIDocShellTreeNode* aNode, PRBool aForward, nsIDocShell** aDocShell);
|
||||
PRBool FocusNextChild(nsIBaseWindow * aCurrentFocus, PRBool aForward);
|
||||
void MakeSureOfSetFocus(nsIBaseWindow * aCurrentFocus, nsIDocShell* aDocShell = nsnull);
|
||||
|
||||
//
|
||||
// Helper method that is called when a new document (including any
|
||||
// sub-documents - ie. frames) has been completely loaded.
|
||||
|
||||
@@ -198,13 +198,6 @@ interface nsIDocShell : nsISupports
|
||||
*/
|
||||
attribute boolean allowSubframes;
|
||||
|
||||
/**
|
||||
* Attribute stating whether the document itself should come before
|
||||
* its focusable content in tab traversal (the default is for the document
|
||||
* to be focused last).
|
||||
*/
|
||||
attribute boolean focusDocBeforeContent;
|
||||
|
||||
/**
|
||||
* Attribute stating whether or not images should be loaded.
|
||||
*/
|
||||
@@ -263,6 +256,13 @@ interface nsIDocShell : nsISupports
|
||||
*/
|
||||
attribute boolean canvasHasFocus;
|
||||
|
||||
/*
|
||||
* Tells the docshell to offer focus to its tree owner.
|
||||
* This is currently only necessary for embedding chrome.
|
||||
*/
|
||||
void tabToTreeOwner(in boolean forward,
|
||||
out boolean tookFocus);
|
||||
|
||||
/**
|
||||
* Current busy state for DocShell
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "prlog.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
|
||||
#ifdef INCLUDE_XUL
|
||||
#include "nsIDOMXULDocument.h"
|
||||
@@ -111,6 +113,16 @@ nsFocusController::SetFocusedElement(nsIDOMElement* aElement)
|
||||
NS_IMETHODIMP
|
||||
nsFocusController::SetFocusedWindow(nsIDOMWindowInternal* aWindow)
|
||||
{
|
||||
if (aWindow && (mCurrentWindow != aWindow)) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aWindow);
|
||||
if (sgo) {
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
sgo->GetDocShell(getter_AddRefs(docShell));
|
||||
nsCOMPtr<nsIBaseWindow> basewin = do_QueryInterface(docShell);
|
||||
if (basewin)
|
||||
basewin->SetFocus();
|
||||
}
|
||||
}
|
||||
mCurrentWindow = aWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -217,7 +229,7 @@ nsFocusController::MoveFocus(PRBool aForward, nsIDOMElement* aElt)
|
||||
presContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
if (esm)
|
||||
// Make this ESM shift the focus per our instructions.
|
||||
esm->MoveFocus(aForward, content);
|
||||
esm->ShiftFocus(aForward, content);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -666,13 +666,6 @@ NS_IMETHODIMP nsDocShellTreeOwner::SetFocus()
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellTreeOwner::FocusAvailable(nsIBaseWindow* aCurrentFocus,
|
||||
PRBool aForward,
|
||||
PRBool* aTookFocus)
|
||||
{
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocShellTreeOwner::GetTitle(PRUnichar** aTitle)
|
||||
{
|
||||
if (mOwnerWin)
|
||||
|
||||
@@ -51,6 +51,9 @@ interface nsIWebBrowserSetup : nsISupports
|
||||
/* SETUP_FOCUS_DOC_BEFORE_CONTENT lets an embeddor control whether the document
|
||||
* as a whole gets focus before traversing the document's content, or after
|
||||
* traversing its content.
|
||||
*
|
||||
* NOTE: this property is obsolete and now has no effect
|
||||
*
|
||||
*/
|
||||
|
||||
const unsigned long SETUP_FOCUS_DOC_BEFORE_CONTENT = 6;
|
||||
|
||||
@@ -686,9 +686,7 @@ NS_IMETHODIMP nsWebBrowser::SetProperty(PRUint32 aId, PRUint32 aValue)
|
||||
break;
|
||||
case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT:
|
||||
{
|
||||
NS_ENSURE_STATE(mDocShell);
|
||||
NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
|
||||
mDocShell->SetFocusDocBeforeContent(aValue);
|
||||
// obsolete
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1121,38 +1119,6 @@ NS_IMETHODIMP nsWebBrowser::SetFocus()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWebBrowser::FocusAvailable(nsIBaseWindow* aCurrentFocus,
|
||||
PRBool aForward,
|
||||
PRBool* aTookFocus)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTookFocus);
|
||||
|
||||
// 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(nsnull /*mTreeOwner*/);
|
||||
|
||||
//If the current focus is us, offer it to the next owner.
|
||||
if(aCurrentFocus == NS_STATIC_CAST(nsIBaseWindow*, this))
|
||||
{
|
||||
if(nextCallWin)
|
||||
return nextCallWin->FocusAvailable(aCurrentFocus,
|
||||
aForward, aTookFocus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//Otherwise, check the chilren and offer it to the next sibling.
|
||||
if((mDocShellAsWin.get() != aCurrentFocus) &&
|
||||
NS_SUCCEEDED(mDocShellAsWin->SetFocus()))
|
||||
{
|
||||
*aTookFocus = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWebBrowser::GetTitle(PRUnichar** aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTitle);
|
||||
|
||||
@@ -36,9 +36,13 @@
|
||||
* Child frames are traversed before their parents going both forward
|
||||
* and backward.
|
||||
*
|
||||
* EXTENSIVE_PREORDER:
|
||||
* Like EXTENSIVE, but traverse parent frames before their children
|
||||
* when going forward.
|
||||
* FOCUS:
|
||||
* Traverse frames in "focus" order, which is like extensive but
|
||||
* does a strict preorder traversal in both directions. This type of
|
||||
* traversal also handles placeholder frames transparently, meaning that
|
||||
* it will never stop on one - going down will get the real frame, going
|
||||
* back up will go on past the placeholder, so the placeholders are logically
|
||||
* part of the frame tree.
|
||||
*
|
||||
* FASTEST:
|
||||
* XXX not implemented
|
||||
@@ -50,7 +54,7 @@
|
||||
enum nsTraversalType{
|
||||
LEAF,
|
||||
EXTENSIVE,
|
||||
EXTENSIVE_PREORDER,
|
||||
FOCUS,
|
||||
FASTEST
|
||||
#ifdef IBMBIDI // Simon
|
||||
, VISUAL
|
||||
|
||||
@@ -270,6 +270,14 @@ public:
|
||||
NS_IMETHOD SetSubShellFor(nsIContent* aContent,
|
||||
nsISupports* aSubShell) = 0;
|
||||
|
||||
/**
|
||||
* Find the content in the map that has aSubShell set
|
||||
* as its subshell. If there is more than one mapping for
|
||||
* aSubShell, the result is undefined.
|
||||
*/
|
||||
NS_IMETHOD FindContentForShell(nsISupports* aSubShell,
|
||||
nsIContent** aContent) const = 0;
|
||||
|
||||
/**
|
||||
* Gets the placeholder frame associated with the specified frame. This is
|
||||
* a helper frame that forwards the request to the frame manager.
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
|
||||
#include "nsFrameTraversal.h"
|
||||
#include "nsFrameList.h"
|
||||
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
#include "nsPlaceholderFrame.h"
|
||||
|
||||
|
||||
class nsFrameIterator: public nsIBidirectionalEnumerator
|
||||
@@ -84,8 +82,6 @@ public:
|
||||
nsLeafIterator(nsIPresContext* aPresContext, nsIFrame *start);
|
||||
void SetExtensive(PRBool aExtensive) {mExtensive = aExtensive;}
|
||||
PRBool GetExtensive(){return mExtensive;}
|
||||
void SetPreOrder(PRBool aPreOrder) { mPreOrder = aPreOrder; }
|
||||
PRBool GetPreOrder() { return mPreOrder; }
|
||||
|
||||
private :
|
||||
|
||||
@@ -95,7 +91,44 @@ private :
|
||||
|
||||
nsIPresContext* mPresContext;
|
||||
PRPackedBool mExtensive;
|
||||
PRPackedBool mPreOrder;
|
||||
};
|
||||
|
||||
class nsFocusIterator : public nsFrameIterator
|
||||
{
|
||||
public:
|
||||
nsFocusIterator(nsIPresContext* aPresContext, nsIFrame* aStart);
|
||||
private:
|
||||
NS_IMETHOD Next();
|
||||
NS_IMETHOD Prev();
|
||||
NS_IMETHOD Last();
|
||||
|
||||
/*
|
||||
Our own versions of the standard frame tree navigation
|
||||
methods, which apply the following rules for placeholder
|
||||
frames:
|
||||
|
||||
- If a frame HAS a placeholder frame, getting its parent
|
||||
gets the placeholder's parent.
|
||||
|
||||
- If a frame's first child or next/prev sibling IS a
|
||||
placeholder frame, then we instead return the real frame.
|
||||
|
||||
- If a frame HAS a placeholder frame, getting its next/prev
|
||||
sibling gets the placeholder frame's next/prev sibling.
|
||||
|
||||
These are all applied recursively to support multiple levels of
|
||||
placeholders.
|
||||
*/
|
||||
|
||||
nsIFrame* GetParentFrame(nsIFrame* aFrame);
|
||||
nsIFrame* GetFirstChild(nsIFrame* aFrame);
|
||||
nsIFrame* GetNextSibling(nsIFrame* aFrame);
|
||||
nsIFrame* GetPrevSibling(nsIFrame* aFrame);
|
||||
|
||||
nsIFrame* GetRealFrame(nsIFrame* aFrame);
|
||||
nsIFrame* GetPlaceholderFrame(nsIFrame* aFrame);
|
||||
|
||||
nsIPresContext* mPresContext;
|
||||
};
|
||||
|
||||
#ifdef IBMBIDI // Simon
|
||||
@@ -148,7 +181,6 @@ NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
|
||||
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
|
||||
NS_ADDREF(trav);
|
||||
trav->SetExtensive(PR_FALSE);
|
||||
trav->SetPreOrder(PR_FALSE);
|
||||
}
|
||||
break;
|
||||
case EXTENSIVE:{
|
||||
@@ -158,17 +190,14 @@ NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
|
||||
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
|
||||
NS_ADDREF(trav);
|
||||
trav->SetExtensive(PR_TRUE);
|
||||
trav->SetPreOrder(PR_FALSE);
|
||||
}
|
||||
break;
|
||||
case EXTENSIVE_PREORDER: {
|
||||
nsLeafIterator *trav = new nsLeafIterator(aPresContext, aStart);
|
||||
case FOCUS: {
|
||||
nsFocusIterator *trav = new nsFocusIterator(aPresContext, aStart);
|
||||
if (!trav)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
|
||||
NS_ADDREF(trav);
|
||||
trav->SetExtensive(PR_TRUE);
|
||||
trav->SetPreOrder(PR_TRUE);
|
||||
}
|
||||
break;
|
||||
#ifdef IBMBIDI
|
||||
@@ -303,15 +332,12 @@ nsLeafIterator::Next()
|
||||
nsIFrame *parent = getCurrent();
|
||||
if (!parent)
|
||||
parent = getLast();
|
||||
if (!mExtensive && !mPreOrder)
|
||||
if (!mExtensive)
|
||||
{
|
||||
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
|
||||
{
|
||||
parent = result;
|
||||
}
|
||||
} else if (mPreOrder) {
|
||||
if (NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull, &result)) && result)
|
||||
parent = result;
|
||||
}
|
||||
if (parent != getCurrent())
|
||||
{
|
||||
@@ -319,15 +345,13 @@ nsLeafIterator::Next()
|
||||
}
|
||||
else {
|
||||
while(parent && !IsRootFrame(parent)) {
|
||||
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result) {
|
||||
if (!mPreOrder) {
|
||||
parent = result;
|
||||
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
|
||||
{
|
||||
parent = result;
|
||||
}
|
||||
result = parent;
|
||||
}
|
||||
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result) {
|
||||
parent = result;
|
||||
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
|
||||
{
|
||||
parent = result;
|
||||
}
|
||||
result = parent;
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -340,7 +364,7 @@ nsLeafIterator::Next()
|
||||
else
|
||||
{
|
||||
parent = result;
|
||||
if (mExtensive && !mPreOrder)
|
||||
if (mExtensive)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -404,6 +428,199 @@ nsLeafIterator::Prev()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsFocusIterator::nsFocusIterator(nsIPresContext* aPresContext, nsIFrame* aStart)
|
||||
: mPresContext(aPresContext)
|
||||
{
|
||||
nsIFrame* start = aStart;
|
||||
if (aStart)
|
||||
start = GetRealFrame(aStart);
|
||||
|
||||
setStart(start);
|
||||
setCurrent(start);
|
||||
setLast(start);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFocusIterator::GetPlaceholderFrame(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* result = aFrame;
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mPresContext->GetShell(getter_AddRefs(presShell));
|
||||
if (presShell) {
|
||||
nsIFrame* placeholder = 0;
|
||||
presShell->GetPlaceholderFrameFor(aFrame, &placeholder);
|
||||
if (placeholder)
|
||||
result = placeholder;
|
||||
}
|
||||
|
||||
if (result != aFrame)
|
||||
result = GetPlaceholderFrame(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFocusIterator::GetRealFrame(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* result = aFrame;
|
||||
|
||||
// See if it's a placeholder frame for a floater.
|
||||
if (aFrame) {
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
aFrame->GetFrameType(getter_AddRefs(frameType));
|
||||
PRBool isPlaceholder = (nsLayoutAtoms::placeholderFrame == frameType.get());
|
||||
if (isPlaceholder) {
|
||||
// Get the out-of-flow frame that the placeholder points to.
|
||||
// This is the real floater that we should examine.
|
||||
result = NS_STATIC_CAST(nsPlaceholderFrame*,aFrame)->GetOutOfFlowFrame();
|
||||
NS_ASSERTION(result, "No out of flow frame found for placeholder!\n");
|
||||
}
|
||||
|
||||
if (result != aFrame)
|
||||
result = GetRealFrame(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFocusIterator::GetParentFrame(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* result = 0;
|
||||
nsIFrame* placeholder = GetPlaceholderFrame(aFrame);
|
||||
if (placeholder)
|
||||
placeholder->GetParent(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFocusIterator::GetFirstChild(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* result = 0;
|
||||
aFrame->FirstChild(mPresContext, nsnull, &result);
|
||||
if (result)
|
||||
result = GetRealFrame(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFocusIterator::GetNextSibling(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* result = 0;
|
||||
nsIFrame* placeholder = GetPlaceholderFrame(aFrame);
|
||||
if (placeholder) {
|
||||
placeholder->GetNextSibling(&result);
|
||||
if (result)
|
||||
result = GetRealFrame(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFocusIterator::GetPrevSibling(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame* result = 0;
|
||||
nsIFrame* placeholder = GetPlaceholderFrame(aFrame);
|
||||
if (placeholder) {
|
||||
nsIFrame* parent = GetParentFrame(placeholder);
|
||||
if (parent) {
|
||||
nsIFrame* child = 0;
|
||||
parent->FirstChild(mPresContext, nsnull, &child);
|
||||
nsFrameList list(child);
|
||||
result = list.GetPrevSiblingFor(placeholder);
|
||||
result = GetRealFrame(result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusIterator::Next()
|
||||
{
|
||||
nsIFrame* result = 0;
|
||||
nsIFrame* parent = getCurrent();
|
||||
if (!parent)
|
||||
parent = getLast();
|
||||
|
||||
if ((result = GetFirstChild(parent)))
|
||||
parent = result;
|
||||
|
||||
result = parent;
|
||||
if (result == getCurrent()) {
|
||||
while (result && !IsRootFrame(result)) {
|
||||
if ((parent = GetNextSibling(result))) {
|
||||
result = parent;
|
||||
break;
|
||||
} else {
|
||||
parent = result;
|
||||
result = GetParentFrame(parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!result || IsRootFrame(result)) {
|
||||
result = 0;
|
||||
setLast(parent);
|
||||
}
|
||||
}
|
||||
|
||||
setCurrent(result);
|
||||
if (!result)
|
||||
setOffEdge(1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusIterator::Prev()
|
||||
{
|
||||
nsIFrame *result;
|
||||
nsIFrame *parent = getCurrent();
|
||||
if (!parent)
|
||||
parent = getLast();
|
||||
if (parent) {
|
||||
if ((result = GetPrevSibling(parent))) {
|
||||
parent = result;
|
||||
while ((result = GetFirstChild(parent))) {
|
||||
parent = result;
|
||||
while ((result = GetNextSibling(parent)))
|
||||
parent = result;
|
||||
}
|
||||
result = parent;
|
||||
} else if (!(result = GetParentFrame(parent))) {
|
||||
result = 0;
|
||||
setLast(parent);
|
||||
}
|
||||
}
|
||||
|
||||
setCurrent(result);
|
||||
if (!result)
|
||||
setOffEdge(-1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFocusIterator::Last()
|
||||
{
|
||||
nsIFrame* result;
|
||||
nsIFrame* parent = getCurrent();
|
||||
while (!IsRootFrame(parent) && (result = GetParentFrame(parent)))
|
||||
parent = result;
|
||||
|
||||
while ((result = GetFirstChild(parent))) {
|
||||
parent = result;
|
||||
while ((result = GetNextSibling(parent)))
|
||||
parent = result;
|
||||
}
|
||||
|
||||
setCurrent(parent);
|
||||
if (!parent)
|
||||
setOffEdge(1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef IBMBIDI
|
||||
|
||||
/*********VISUALITERATOR**********/
|
||||
|
||||
@@ -151,7 +151,6 @@ public:
|
||||
|
||||
protected:
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
void DrawDottedRect(nsIRenderingContext& aRenderingContext, nsRect& aRect);
|
||||
|
||||
// Data members
|
||||
PRPackedBool mDoPaintFocus;
|
||||
@@ -366,26 +365,6 @@ CanvasFrame::RemoveFrame(nsIPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasFrame::DrawDottedRect(nsIRenderingContext& aRenderingContext, nsRect& aRect)
|
||||
{
|
||||
#ifdef DEBUG_CANVAS_FOCUS
|
||||
printf("** DrawDottedRect: %d,%d,%d,%d\n",aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
#endif
|
||||
|
||||
aRenderingContext.DrawLine(aRect.x, aRect.y,
|
||||
aRect.x+aRect.width, aRect.y);
|
||||
aRenderingContext.DrawLine(aRect.x+aRect.width, aRect.y,
|
||||
aRect.x+aRect.width, aRect.y+aRect.height);
|
||||
aRenderingContext.DrawLine(aRect.x+aRect.width, aRect.y+aRect.height,
|
||||
aRect.x, aRect.y+aRect.height);
|
||||
aRenderingContext.DrawLine(aRect.x, aRect.y+aRect.height,
|
||||
aRect.x, aRect.y);
|
||||
aRenderingContext.DrawLine(aRect.x, aRect.y+aRect.height,
|
||||
aRect.x, aRect.y);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
CanvasFrame::Paint(nsIPresContext* aPresContext,
|
||||
nsIRenderingContext& aRenderingContext,
|
||||
@@ -423,7 +402,6 @@ CanvasFrame::Paint(nsIPresContext* aPresContext,
|
||||
#endif
|
||||
|
||||
if (mDoPaintFocus) {
|
||||
aRenderingContext.PushState();
|
||||
PRBool clipEmpty;
|
||||
nsRect focusRect;
|
||||
GetRect(focusRect);
|
||||
@@ -454,29 +432,37 @@ CanvasFrame::Paint(nsIPresContext* aPresContext,
|
||||
scrollableView->GetClipView(&clippedView);
|
||||
nsRect vcr;
|
||||
clippedView->GetBounds(vcr);
|
||||
focusRect.width = vcr.width;
|
||||
focusRect.height = vcr.height;
|
||||
nscoord x,y;
|
||||
scrollableView->GetScrollPosition(x, y);
|
||||
focusRect.x += x;
|
||||
focusRect.y += y;
|
||||
}
|
||||
aRenderingContext.SetLineStyle(nsLineStyle_kDotted);
|
||||
aRenderingContext.SetColor(NS_RGB(0,0,0));
|
||||
|
||||
nsStyleOutline outlineStyle(aPresContext);
|
||||
outlineStyle.SetOutlineStyle(NS_STYLE_BORDER_STYLE_DOTTED);
|
||||
outlineStyle.SetOutlineInvert();
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
// XXX the CSS border for links is specified as 2px, but it
|
||||
// is only drawn as 1px. Match this here.
|
||||
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
|
||||
|
||||
focusRect.width -= onePixel;
|
||||
focusRect.height -= onePixel;
|
||||
nsRect borderInside(focusRect.x + onePixel,
|
||||
focusRect.y + onePixel,
|
||||
focusRect.width - 2 * onePixel,
|
||||
focusRect.height - 2 * onePixel);
|
||||
|
||||
DrawDottedRect(aRenderingContext, focusRect);
|
||||
|
||||
focusRect.Deflate(onePixel, onePixel);
|
||||
DrawDottedRect(aRenderingContext, focusRect);
|
||||
nsCSSRendering::DrawDashedSides(0, aRenderingContext,
|
||||
focusRect, nsnull,
|
||||
nsnull, &outlineStyle,
|
||||
PR_TRUE, focusRect,
|
||||
borderInside, 0,
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
aRenderingContext.PopState(clipEmpty);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
||||
@@ -790,6 +790,29 @@ DummyLayoutRequest::Cancel(nsresult status)
|
||||
return rv;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// A generic nsDSTNodeFunctor to look for a specific value in the map
|
||||
|
||||
class nsSearchEnumerator : public nsDSTNodeFunctor
|
||||
{
|
||||
public:
|
||||
nsSearchEnumerator(void* aTargetValue)
|
||||
: mTargetValue(aTargetValue) {
|
||||
mResultKey = nsnull;
|
||||
}
|
||||
|
||||
void operator() (void* aKey, void* aValue) {
|
||||
if (aValue == mTargetValue)
|
||||
mResultKey = aKey;
|
||||
}
|
||||
|
||||
void* GetResult() { return mResultKey; }
|
||||
|
||||
private:
|
||||
void* mResultKey;
|
||||
void* mTargetValue;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class PresShell : public nsIPresShell, public nsIViewObserver,
|
||||
@@ -855,6 +878,8 @@ public:
|
||||
nsISupports** aResult) const;
|
||||
NS_IMETHOD SetSubShellFor(nsIContent* aContent,
|
||||
nsISupports* aSubShell);
|
||||
NS_IMETHOD FindContentForShell(nsISupports* aSubShell,
|
||||
nsIContent** aContent) const;
|
||||
NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
nsIFrame** aPlaceholderFrame) const;
|
||||
NS_IMETHOD AppendReflowCommand(nsIReflowCommand* aReflowCommand);
|
||||
@@ -5335,6 +5360,24 @@ PresShell::SetSubShellFor(nsIContent* aContent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::FindContentForShell(nsISupports* aSubShell,
|
||||
nsIContent** aContent) const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSubShell);
|
||||
NS_ENSURE_ARG_POINTER(aContent);
|
||||
*aContent = nsnull;
|
||||
|
||||
if (!mSubShellMap)
|
||||
return NS_OK;
|
||||
|
||||
nsSearchEnumerator enumerator(NS_STATIC_CAST(void*, aSubShell));
|
||||
mSubShellMap->Enumerate(enumerator);
|
||||
*aContent = NS_STATIC_CAST(nsIContent*, enumerator.GetResult());
|
||||
NS_IF_ADDREF(*aContent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
|
||||
|
||||
@@ -385,6 +385,7 @@ frameset {
|
||||
|
||||
frame {
|
||||
background-color: transparent ! important; /* (b=49779) */
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
iframe {
|
||||
|
||||
@@ -400,15 +400,6 @@ NS_IMETHODIMP nsBrowserWindow::SetFocus()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBrowserWindow::FocusAvailable(nsIBaseWindow* aCurrentFocus,
|
||||
PRBool aForward,
|
||||
PRBool* aTookFocus)
|
||||
{
|
||||
//XXX First Check In
|
||||
NS_ASSERTION(PR_FALSE, "Not Yet Implemented");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBrowserWindow::GetTitle(PRUnichar** aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTitle);
|
||||
@@ -2090,12 +2081,6 @@ nsBrowserWindow::FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aRes
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBrowserWindow::FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
|
||||
@@ -124,7 +124,6 @@ public:
|
||||
nsIWebShell *&aNewWebShell);
|
||||
NS_IMETHOD ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode);
|
||||
NS_IMETHOD FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult);
|
||||
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken);
|
||||
|
||||
// nsBrowserWindow
|
||||
void SetWebCrawler(nsWebCrawler* aWebCrawler);
|
||||
|
||||
@@ -186,21 +186,6 @@ interface nsIBaseWindow : nsISupports
|
||||
*/
|
||||
void setFocus();
|
||||
|
||||
/* This is called when focus is available for the taking because of
|
||||
tabbing through an object. In any case this is called on an object to
|
||||
allow it to take focus if it desires. If the aCurrentFocus object is
|
||||
the object being called, then the object being called should offer focus to
|
||||
it's parent. If the aCurrentFocus is a child of the object being called,
|
||||
the object being called should set the focus to the next sibling to the
|
||||
aCurrentFocus object. Otherwise it should take focus for itself. If the
|
||||
object being called can not take focus for itself it should offer focus to
|
||||
it's parent. Note an object should not take focus for itself by giving it
|
||||
to a child. In most cases this function is being called because the child
|
||||
is trying to give up focus. */
|
||||
void focusAvailable(in nsIBaseWindow aCurrentFocus,
|
||||
in boolean aForward,
|
||||
out boolean aTookFocus);
|
||||
|
||||
/*
|
||||
Title of the window.
|
||||
*/
|
||||
|
||||
@@ -2442,6 +2442,9 @@ BOOL nsWindow::OnKeyDown( UINT aVirtualKeyCode, UINT aScanCode)
|
||||
{
|
||||
DispatchKeyEvent(NS_KEY_PRESS, 0, aVirtualKeyCode);
|
||||
}
|
||||
else if (mIsControlDown && aVirtualKeyCode == NS_VK_TAB) {
|
||||
DispatchKeyEvent(NS_KEY_PRESS, 0, NS_VK_TAB);
|
||||
}
|
||||
else if (mIsControlDown && aVirtualKeyCode == NS_VK_SUBTRACT) {
|
||||
DispatchKeyEvent(NS_KEY_PRESS, aVirtualKeyCode-64, 0);
|
||||
}
|
||||
|
||||
@@ -311,13 +311,6 @@ NS_IMETHODIMP nsChromeTreeOwner::SetFocus()
|
||||
return mXULWindow->SetFocus();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChromeTreeOwner::FocusAvailable(nsIBaseWindow* aCurrentFocus,
|
||||
PRBool aForward,
|
||||
PRBool* aTookFocus)
|
||||
{
|
||||
return mXULWindow->FocusAvailable(aCurrentFocus, aForward, aTookFocus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsChromeTreeOwner::GetTitle(PRUnichar** aTitle)
|
||||
{
|
||||
return mXULWindow->GetTitle(aTitle);
|
||||
|
||||
@@ -533,13 +533,6 @@ NS_IMETHODIMP nsContentTreeOwner::SetFocus()
|
||||
return mXULWindow->SetFocus();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsContentTreeOwner::FocusAvailable(nsIBaseWindow* aCurrentFocus,
|
||||
PRBool aForward,
|
||||
PRBool* aTookFocus)
|
||||
{
|
||||
return mXULWindow->FocusAvailable(aCurrentFocus, aForward, aTookFocus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsContentTreeOwner::GetTitle(PRUnichar** aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTitle);
|
||||
|
||||
@@ -601,13 +601,6 @@ NS_IMETHODIMP nsXULWindow::SetFocus()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULWindow::FocusAvailable(nsIBaseWindow* aCurrentFocus,
|
||||
PRBool aForward,
|
||||
PRBool* aTookFocus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULWindow::GetTitle(PRUnichar** aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTitle);
|
||||
|
||||
@@ -15,6 +15,19 @@
|
||||
<content orient="vertical"/>
|
||||
|
||||
<implementation>
|
||||
<property name="handleCtrlTab">
|
||||
<setter>
|
||||
<![CDATA[
|
||||
this.setAttribute("handleCtrlTab", val);
|
||||
]]>
|
||||
</setter>
|
||||
<getter>
|
||||
<![CDATA[
|
||||
return this.getAttribute("handleCtrlTab");
|
||||
]]>
|
||||
</getter>
|
||||
</property>
|
||||
|
||||
<property name="selectedTab">
|
||||
<setter>
|
||||
<![CDATA[
|
||||
@@ -49,8 +62,10 @@
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"tabs");
|
||||
tabs = tabs.length ? tabs[0] : null;
|
||||
if (tabs)
|
||||
if (tabs && (this.handleCtrlTab != "false")) {
|
||||
tabs.advanceSelectedTab(1);
|
||||
event.preventDefault();
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
|
||||
@@ -60,8 +75,10 @@
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"tabs");
|
||||
tabs = tabs.length ? tabs[0] : null;
|
||||
if (tabs)
|
||||
if (tabs && (this.handleCtrlTab != "false")) {
|
||||
tabs.advanceSelectedTab(-1);
|
||||
event.preventDefault();
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
</handlers>
|
||||
@@ -133,10 +150,20 @@
|
||||
<parameter name="aDir"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var next = this.selectedTab[aDir == -1 ? "previousSibling" : "nextSibling"];
|
||||
if (next && !next.getAttribute("hidden")) {
|
||||
var startTab = this.selectedItem;
|
||||
var next = startTab[aDir == -1 ? "previousSibling" : "nextSibling"];
|
||||
|
||||
while (next != startTab && (!next || next.getAttribute("hidden"))) {
|
||||
if (next && next.getAttribute("hidden"))
|
||||
next = next[aDir == -1 ? "previousSibling" : "nextSibling"];
|
||||
if (!next)
|
||||
next = aDir == 1 ? this.childNodes[0] : this.childNodes[this.childNodes.length - 1];
|
||||
}
|
||||
|
||||
if (next && next != startTab) {
|
||||
this.selectedTab = next;
|
||||
next.focus();
|
||||
document.commandDispatcher.advanceFocusIntoSubtree(next);
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
|
||||
@@ -45,7 +45,10 @@ bindings, binding, content, member, triple {
|
||||
checkbox,
|
||||
colorpicker[type="button"],
|
||||
menulist,
|
||||
outliner {
|
||||
outliner,
|
||||
browser,
|
||||
editor,
|
||||
iframe {
|
||||
-moz-user-focus: normal;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user