Bug 516076, pass a contextual window to focus controller methods, so that it retrieves the controller for the right window, r=neil,sr=smaug

This commit is contained in:
Neil Deakin 2009-09-21 13:39:44 -04:00
Родитель f7679e8fd8
Коммит dc9b8b8573
17 изменённых файлов: 71 добавлений и 75 удалений

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

@ -55,7 +55,6 @@
#include "nsUnicharUtils.h"
#include "nsIPrivateDOMEvent.h"
#include "nsIEventStateManager.h"
#include "nsIFocusController.h"
#include "nsContentList.h"
#include "nsIObserver.h"
#include "nsIBaseWindow.h"

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

@ -4417,7 +4417,7 @@ nsEventStateManager::DoContentCommandEvent(nsContentCommandEvent* aEvent)
return NS_ERROR_NOT_IMPLEMENTED;
}
nsCOMPtr<nsIController> controller;
nsresult rv = fc->GetControllerForCommand(cmd, getter_AddRefs(controller));
nsresult rv = fc->GetControllerForCommand(window, cmd, getter_AddRefs(controller));
NS_ENSURE_SUCCESS(rv, rv);
if (!controller) {
// When GetControllerForCommand succeeded but there is no controller, the

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

@ -59,7 +59,6 @@ class nsIPresShell;
class nsIDocShell;
class nsIDocShellTreeNode;
class nsIDocShellTreeItem;
class nsIFocusController;
class imgIContainer;
class nsDOMDataTransfer;

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

@ -45,7 +45,6 @@ class nsIContent;
class nsPIDOMWindow;
class nsPresContext;
class nsIWidget;
class nsIFocusController;
class nsTextStateManager;
class nsISelection;

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

@ -112,7 +112,6 @@
#include "nsLayoutUtils.h"
#include "nsContentCreatorFunctions.h"
#include "mozAutoDocUpdate.h"
#include "nsIFocusController.h"
class nsINodeInfo;
class nsIDOMNodeList;

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

@ -417,6 +417,8 @@ nsXBLPrototypeHandler::DispatchXBLCommand(nsPIDOMEventTarget* aTarget, nsIDOMEve
nsCOMPtr<nsPIWindowRoot> windowRoot(do_QueryInterface(aTarget));
if (windowRoot) {
windowRoot->GetFocusController(getter_AddRefs(focusController));
if (windowRoot)
privateWindow = do_QueryInterface(windowRoot->GetWindow());
}
else {
privateWindow = do_QueryInterface(aTarget);
@ -446,7 +448,7 @@ nsXBLPrototypeHandler::DispatchXBLCommand(nsPIDOMEventTarget* aTarget, nsIDOMEve
NS_LossyConvertUTF16toASCII command(mHandlerText);
if (focusController)
focusController->GetControllerForCommand(command.get(), getter_AddRefs(controller));
focusController->GetControllerForCommand(privateWindow, command.get(), getter_AddRefs(controller));
else
controller = GetController(aTarget); // We're attached to the receiver possibly.

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

@ -369,7 +369,8 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventTy
nsCOMPtr<nsIFocusController> fc;
root->GetFocusController(getter_AddRefs(fc));
if (fc) {
fc->GetControllers(getter_AddRefs(controllers));
nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(root->GetWindow());
fc->GetControllers(piWindow, getter_AddRefs(controllers));
}
}

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

@ -489,7 +489,7 @@ nsXULCommandDispatcher::GetControllers(nsIControllers** aResult)
nsIFocusController* fc = GetFocusController();
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
return fc->GetControllers(aResult);
return fc->GetControllers(mDocument->GetWindow(), aResult);
}
NS_IMETHODIMP
@ -498,7 +498,7 @@ nsXULCommandDispatcher::GetControllerForCommand(const char *aCommand, nsIControl
nsIFocusController* fc = GetFocusController();
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
return fc->GetControllerForCommand(aCommand, _retval);
return fc->GetControllerForCommand(mDocument->GetWindow(), aCommand, _retval);
}
NS_IMETHODIMP

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

@ -10579,7 +10579,7 @@ nsDocShell::GetControllerForCommand(const char * inCommand,
if (window) {
nsIFocusController *focusController = window->GetRootFocusController();
if (focusController)
rv = focusController->GetControllerForCommand (inCommand, outController);
rv = focusController->GetControllerForCommand (window, inCommand, outController);
} // if window
return rv;

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

@ -78,6 +78,22 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFocusController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPopupNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
static nsIContent*
GetRootFocusedContentAndWindow(nsPIDOMWindow* aContextWindow,
nsPIDOMWindow** aWindow)
{
*aWindow = nsnull;
if (aContextWindow) {
nsCOMPtr<nsPIDOMWindow> rootWindow = aContextWindow->GetPrivateRoot();
if (rootWindow) {
return nsFocusManager::GetFocusedDescendant(rootWindow, PR_TRUE, aWindow);
}
}
return nsnull;
}
NS_IMETHODIMP
nsFocusController::Create(nsIFocusController** aResult)
{
@ -91,81 +107,58 @@ nsFocusController::Create(nsIFocusController** aResult)
}
NS_IMETHODIMP
nsFocusController::GetControllers(nsIControllers** aResult)
nsFocusController::GetControllers(nsPIDOMWindow* aContextWindow, nsIControllers** aResult)
{
*aResult = nsnull;
// XXX: we should fix this so there's a generic interface that
// describes controllers, so this code would have no special
// knowledge of what object might have controllers.
nsCOMPtr<nsIDOMElement> focusedElement;
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (!fm) {
*aResult = nsnull;
return NS_OK;
}
fm->GetFocusedElement(getter_AddRefs(focusedElement));
if (focusedElement) {
nsCOMPtr<nsPIDOMWindow> focusedWindow;
nsIContent* focusedContent =
GetRootFocusedContentAndWindow(aContextWindow, getter_AddRefs(focusedWindow));
if (focusedContent) {
#ifdef MOZ_XUL
nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(focusedElement));
nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(focusedContent));
if (xulElement)
return xulElement->GetControllers(aResult);
#endif
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextArea =
do_QueryInterface(focusedElement);
do_QueryInterface(focusedContent);
if (htmlTextArea)
return htmlTextArea->GetControllers(aResult);
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement =
do_QueryInterface(focusedElement);
do_QueryInterface(focusedContent);
if (htmlInputElement)
return htmlInputElement->GetControllers(aResult);
nsCOMPtr<nsIContent> content = do_QueryInterface(focusedElement);
if (content && content->IsEditable()) {
// Move up to the window.
nsCOMPtr<nsIDOMDocument> domDoc;
focusedElement->GetOwnerDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMWindowInternal> domWindow =
do_QueryInterface(GetWindowFromDocument(domDoc));
if (domWindow)
return domWindow->GetControllers(aResult);
}
if (focusedContent->IsEditable() && focusedWindow)
return focusedWindow->GetControllers(aResult);
}
else {
nsCOMPtr<nsIDOMWindow> focusedWindow;
fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(focusedWindow);
if (domWindow)
return domWindow->GetControllers(aResult);
}
*aResult = nsnull;
return NS_OK;
}
nsPIDOMWindow *
nsFocusController::GetWindowFromDocument(nsIDOMDocument* aDocument)
{
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
if (!doc)
return nsnull;
return doc->GetWindow();
}
NS_IMETHODIMP
nsFocusController::GetControllerForCommand(const char * aCommand,
nsFocusController::GetControllerForCommand(nsPIDOMWindow* aContextWindow,
const char * aCommand,
nsIController** _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
nsCOMPtr<nsIControllers> controllers;
nsCOMPtr<nsIController> controller;
GetControllers(getter_AddRefs(controllers));
GetControllers(aContextWindow, getter_AddRefs(controllers));
if(controllers) {
controllers->GetControllerForCommand(aCommand, getter_AddRefs(controller));
if(controller) {
@ -174,14 +167,8 @@ nsFocusController::GetControllerForCommand(const char * aCommand,
}
}
nsCOMPtr<nsIDOMElement> focusedElement;
nsCOMPtr<nsIDOMWindow> focusedWindow;
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
fm->GetFocusedElement(getter_AddRefs(focusedElement));
fm->GetFocusedWindow(getter_AddRefs(focusedWindow));
}
nsCOMPtr<nsPIDOMWindow> focusedWindow;
GetRootFocusedContentAndWindow(aContextWindow, getter_AddRefs(focusedWindow));
while (focusedWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow(do_QueryInterface(focusedWindow));

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

@ -49,8 +49,6 @@
#include "nsWeakReference.h"
#include "nsCycleCollectionParticipant.h"
class nsIDOMElement;
class nsIDOMWindow;
class nsPIDOMWindow;
class nsIController;
class nsIControllers;
@ -67,15 +65,14 @@ public:
NS_IMETHOD GetPopupNode(nsIDOMNode** aNode);
NS_IMETHOD SetPopupNode(nsIDOMNode* aNode);
NS_IMETHOD GetControllerForCommand(const char *aCommand, nsIController** aResult);
NS_IMETHOD GetControllers(nsIControllers** aResult);
NS_IMETHOD GetControllerForCommand(nsPIDOMWindow* aContextWindow,
const char *aCommand,
nsIController** aResult);
NS_IMETHOD GetControllers(nsPIDOMWindow* aContextWindow, nsIControllers** aResult);
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFocusController,
nsIFocusController)
public:
static nsPIDOMWindow *GetWindowFromDocument(nsIDOMDocument* aElement);
// Members
protected:
nsCOMPtr<nsIDOMNode> mPopupNode; // [OWNER]

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

@ -900,7 +900,7 @@ nsFocusManager::WindowHidden(nsIDOMWindow* aWindow)
// ensures that the focused window isn't in a chain of frames that doesn't
// exist any more.
if (window != mFocusedWindow) {
nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(window));
nsCOMPtr<nsIWebNavigation> webnav(do_GetInterface(mFocusedWindow));
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
if (dsti) {
nsCOMPtr<nsIDocShellTreeItem> parentDsti;

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

@ -45,14 +45,15 @@
#include "nsISupports.h"
#include "nsCOMPtr.h"
class nsPIDOMWindow;
class nsIDOMNode;
class nsIController;
class nsIControllers;
// 2879DB1C-47AA-46C4-B184-2590CC39F262
// 6D733829-8AE4-43BD-BEEE-35420FE3E932
#define NS_IFOCUSCONTROLLER_IID \
{ 0x2879db1c, 0x47aa, 0x46c4, \
{ 0xb1, 0x84, 0x25, 0x90, 0xcc, 0x39, 0xf2, 0x62 } }
{ 0x6d733829, 0x8ae4, 0x43bd, \
{ 0xbe, 0xee, 0x35, 0x42, 0x0f, 0xe3, 0xe9, 0x32 } }
class nsIFocusController : public nsISupports {
public:
@ -61,8 +62,10 @@ public:
NS_IMETHOD GetPopupNode(nsIDOMNode** aNode)=0;
NS_IMETHOD SetPopupNode(nsIDOMNode* aNode)=0;
NS_IMETHOD GetControllerForCommand(const char * aCommand, nsIController** aResult)=0;
NS_IMETHOD GetControllers(nsIControllers** aResult)=0;
NS_IMETHOD GetControllerForCommand(nsPIDOMWindow* aContextWindow,
const char * aCommand,
nsIController** aResult)=0;
NS_IMETHOD GetControllers(nsPIDOMWindow* aContextWindow, nsIControllers** aResult)=0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFocusController, NS_IFOCUSCONTROLLER_IID)

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

@ -1143,10 +1143,22 @@ function switchWindowTest(otherWindow, framesetWindow)
is(exh, true, "activeWindow set to null");
is(fm.activeWindow, otherWindow, "window not changed when activeWindow set to null");
var topwindow = getTopWindow(framesetWindow);
var topWindow = getTopWindow(framesetWindow);
ok(topWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
"getControllerForCommand for focused window set");
ok(otherWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
"getControllerForCommand for non-focused window set");
ok(topWindow.document.commandDispatcher.getControllerForCommand("cmd_copy") !=
otherWindow.document.commandDispatcher.getControllerForCommand("cmd_copy"),
"getControllerForCommand for two windows different");
ok(topWindow.document.commandDispatcher.getControllers() !=
otherWindow.document.commandDispatcher.getControllers(),
"getControllers for two windows different");
gOldExpectedWindow = otherWindow;
gNewExpectedWindow = framesetWindow.frames[1];
expectFocusShift(function () fm.activeWindow = topwindow,
expectFocusShift(function () fm.activeWindow = topWindow,
gNewExpectedWindow, getById("f4"), true, "switch to frame activeWindow");
fm.clearFocus(otherWindow);

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

@ -347,6 +347,6 @@ nsCommandManager::GetControllerForCommand(const char *aCommand,
return NS_ERROR_FAILURE;
// no target window; send command to focus controller
return focusController->GetControllerForCommand(aCommand, outController);
return focusController->GetControllerForCommand(window, aCommand, outController);
}

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

@ -59,7 +59,6 @@
#include "nsIEventStateManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIFocusController.h"
#include "nsISelectionController.h"
#include "nsISelection.h"
#include "nsIFrame.h"

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

@ -53,7 +53,6 @@
#include "nsMenuPopupFrame.h"
#include "nsGUIEvent.h"
#include "nsUnicharUtils.h"
#include "nsIFocusController.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMDocument.h"
#include "nsPIDOMWindow.h"