зеркало из https://github.com/mozilla/gecko-dev.git
Bug 374584, r=peterv, sr=jst
This commit is contained in:
Родитель
7f372116ec
Коммит
9a2f05e215
|
@ -77,7 +77,7 @@ static PRLogModuleInfo* gLog;
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsXULCommandDispatcher::nsXULCommandDispatcher(nsIDocument* aDocument)
|
||||
: mFocusController(nsnull), mDocument(aDocument), mUpdaters(nsnull)
|
||||
: mDocument(aDocument), mUpdaters(nsnull)
|
||||
{
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -88,50 +88,56 @@ nsXULCommandDispatcher::nsXULCommandDispatcher(nsIDocument* aDocument)
|
|||
|
||||
nsXULCommandDispatcher::~nsXULCommandDispatcher()
|
||||
{
|
||||
while (mUpdaters) {
|
||||
Updater* doomed = mUpdaters;
|
||||
mUpdaters = mUpdaters->mNext;
|
||||
delete doomed;
|
||||
}
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULCommandDispatcher)
|
||||
|
||||
// QueryInterface implementation for nsXULCommandDispatcher
|
||||
NS_INTERFACE_MAP_BEGIN(nsXULCommandDispatcher)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMXULCommandDispatcher)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXULCommandDispatcher)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XULCommandDispatcher)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsXULCommandDispatcher)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULCommandDispatcher)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULCommandDispatcher)
|
||||
|
||||
NS_IMPL_ADDREF(nsXULCommandDispatcher)
|
||||
NS_IMPL_RELEASE(nsXULCommandDispatcher)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULCommandDispatcher)
|
||||
tmp->Disconnect();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::Create(nsIDocument* aDoc, nsIDOMXULCommandDispatcher** aResult)
|
||||
{
|
||||
nsXULCommandDispatcher* dispatcher = new nsXULCommandDispatcher(aDoc);
|
||||
if (!dispatcher)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
*aResult = dispatcher;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULCommandDispatcher)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
|
||||
Updater* updater = tmp->mUpdaters;
|
||||
while (updater) {
|
||||
cb.NoteXPCOMChild(updater->mElement);
|
||||
updater = updater->mNext;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
void
|
||||
nsXULCommandDispatcher::EnsureFocusController()
|
||||
nsXULCommandDispatcher::Disconnect()
|
||||
{
|
||||
if (!mFocusController) {
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mDocument->GetScriptGlobalObject()));
|
||||
|
||||
// An inelegant way to retrieve this to be sure, but we are
|
||||
// guaranteed that the focus controller outlives us, so it
|
||||
// is safe to hold on to it (since we can't die until it has
|
||||
// died).
|
||||
mFocusController = win->GetRootFocusController(); // Store as a weak ptr.
|
||||
while (mUpdaters) {
|
||||
Updater* doomed = mUpdaters;
|
||||
mUpdaters = mUpdaters->mNext;
|
||||
delete doomed;
|
||||
}
|
||||
mDocument = nsnull;
|
||||
}
|
||||
|
||||
nsIFocusController*
|
||||
nsXULCommandDispatcher::GetFocusController()
|
||||
{
|
||||
if (!mDocument) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mDocument->GetScriptGlobalObject()));
|
||||
return win ? win->GetRootFocusController() : nsnull;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@ -140,10 +146,10 @@ nsXULCommandDispatcher::EnsureFocusController()
|
|||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::GetFocusedElement(nsIDOMElement** aElement)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
nsresult rv = mFocusController->GetFocusedElement(aElement);
|
||||
nsresult rv = fc->GetFocusedElement(aElement);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Make sure the caller can access the focused element.
|
||||
|
@ -161,11 +167,11 @@ nsXULCommandDispatcher::GetFocusedElement(nsIDOMElement** aElement)
|
|||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::GetFocusedWindow(nsIDOMWindow** aWindow)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMWindowInternal> window;
|
||||
nsresult rv = mFocusController->GetFocusedWindow(getter_AddRefs(window));
|
||||
nsresult rv = fc->GetFocusedWindow(getter_AddRefs(window));
|
||||
NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && window, rv);
|
||||
|
||||
rv = CallQueryInterface(window, aWindow);
|
||||
|
@ -190,48 +196,42 @@ nsXULCommandDispatcher::GetFocusedWindow(nsIDOMWindow** aWindow)
|
|||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::SetFocusedElement(nsIDOMElement* aElement)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
return mFocusController->SetFocusedElement(aElement);
|
||||
return fc->SetFocusedElement(aElement);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::SetFocusedWindow(nsIDOMWindow* aWindow)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMWindowInternal> window(do_QueryInterface(aWindow));
|
||||
|
||||
return mFocusController->SetFocusedWindow(window);
|
||||
return fc->SetFocusedWindow(window);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::AdvanceFocus()
|
||||
{
|
||||
EnsureFocusController();
|
||||
if (mFocusController)
|
||||
return mFocusController->MoveFocus(PR_TRUE, nsnull);
|
||||
return NS_OK;
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
return fc ? fc->MoveFocus(PR_TRUE, nsnull) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::RewindFocus()
|
||||
{
|
||||
EnsureFocusController();
|
||||
if (mFocusController)
|
||||
return mFocusController->MoveFocus(PR_FALSE, nsnull);
|
||||
return NS_OK;
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
return fc ? fc->MoveFocus(PR_FALSE, nsnull) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::AdvanceFocusIntoSubtree(nsIDOMElement* aElt)
|
||||
{
|
||||
EnsureFocusController();
|
||||
if (mFocusController)
|
||||
return mFocusController->MoveFocus(PR_TRUE, aElt);
|
||||
return NS_OK;
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
return fc ? fc->MoveFocus(PR_TRUE, aElt) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -349,26 +349,18 @@ nsXULCommandDispatcher::RemoveCommandUpdater(nsIDOMElement* aElement)
|
|||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString id;
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
mFocusController->GetFocusedElement(getter_AddRefs(element));
|
||||
fc->GetFocusedElement(getter_AddRefs(element));
|
||||
if (element) {
|
||||
nsresult rv = element->GetAttribute(NS_LITERAL_STRING("id"), id);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get element's id");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
char* actionString = ToNewCString(aEventName);
|
||||
printf("Doing UpdateCommands(\"%s\")\n", actionString);
|
||||
free(actionString);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (Updater* updater = mUpdaters; updater != nsnull; updater = updater->mNext) {
|
||||
// Skip any nodes that don't match our 'events' or 'targets'
|
||||
// filters.
|
||||
|
@ -395,7 +387,7 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
|||
CopyUTF16toUTF8(aEventName, aeventnameC);
|
||||
PR_LOG(gLog, PR_LOG_NOTICE,
|
||||
("xulcmd[%p] update %p event=%s",
|
||||
this, updater->mElement,
|
||||
this, updater->mElement.get(),
|
||||
aeventnameC.get()));
|
||||
}
|
||||
#endif
|
||||
|
@ -449,36 +441,36 @@ nsXULCommandDispatcher::Matches(const nsString& aList,
|
|||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::GetControllers(nsIControllers** aResult)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
return mFocusController->GetControllers(aResult);
|
||||
return fc->GetControllers(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::GetControllerForCommand(const char *aCommand, nsIController** _retval)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
return mFocusController->GetControllerForCommand(aCommand, _retval);
|
||||
return fc->GetControllerForCommand(aCommand, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::GetSuppressFocusScroll(PRBool* aSuppressFocusScroll)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
return mFocusController->GetSuppressFocusScroll(aSuppressFocusScroll);
|
||||
return fc->GetSuppressFocusScroll(aSuppressFocusScroll);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULCommandDispatcher::SetSuppressFocusScroll(PRBool aSuppressFocusScroll)
|
||||
{
|
||||
EnsureFocusController();
|
||||
NS_ENSURE_TRUE(mFocusController, NS_ERROR_FAILURE);
|
||||
nsIFocusController* fc = GetFocusController();
|
||||
NS_ENSURE_TRUE(fc, NS_ERROR_FAILURE);
|
||||
|
||||
return mFocusController->SetSuppressFocusScroll(aSuppressFocusScroll);
|
||||
return fc->SetSuppressFocusScroll(aSuppressFocusScroll);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsIDOMElement;
|
||||
class nsIFocusController;
|
||||
|
@ -59,26 +60,23 @@ class nsIFocusController;
|
|||
class nsXULCommandDispatcher : public nsIDOMXULCommandDispatcher,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
nsXULCommandDispatcher(nsIDocument* aDocument);
|
||||
virtual ~nsXULCommandDispatcher();
|
||||
|
||||
void EnsureFocusController();
|
||||
|
||||
public:
|
||||
|
||||
static NS_IMETHODIMP
|
||||
Create(nsIDocument* aDocument, nsIDOMXULCommandDispatcher** aResult);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULCommandDispatcher,
|
||||
nsIDOMXULCommandDispatcher)
|
||||
|
||||
// nsIDOMXULCommandDispatcher interface
|
||||
NS_DECL_NSIDOMXULCOMMANDDISPATCHER
|
||||
|
||||
void Disconnect();
|
||||
protected:
|
||||
nsIFocusController* mFocusController; // Weak. We always die before the focus controller does.
|
||||
nsIDocument* mDocument; // Weak.
|
||||
nsIFocusController* GetFocusController();
|
||||
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
|
||||
class Updater {
|
||||
public:
|
||||
|
@ -91,10 +89,10 @@ protected:
|
|||
mNext(nsnull)
|
||||
{}
|
||||
|
||||
nsIDOMElement* mElement; // [WEAK]
|
||||
nsString mEvents;
|
||||
nsString mTargets;
|
||||
Updater* mNext;
|
||||
nsCOMPtr<nsIDOMElement> mElement;
|
||||
nsString mEvents;
|
||||
nsString mTargets;
|
||||
Updater* mNext;
|
||||
};
|
||||
|
||||
Updater* mUpdaters;
|
||||
|
|
|
@ -342,6 +342,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULDocument, nsXMLDocument)
|
|||
nsIScriptGlobalObjectOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mMasterPrototype,
|
||||
nsIScriptGlobalObjectOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCommandDispatcher,
|
||||
nsIDOMXULCommandDispatcher)
|
||||
|
||||
PRUint32 i, count = tmp->mPrototypes.Length();
|
||||
for (i = 0; i < count; ++i) {
|
||||
cb.NoteXPCOMChild(NS_STATIC_CAST(nsIScriptGlobalObjectOwner*,
|
||||
|
@ -1928,10 +1931,8 @@ nsXULDocument::Init()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create our command dispatcher and hook it up.
|
||||
rv = nsXULCommandDispatcher::Create(this,
|
||||
getter_AddRefs(mCommandDispatcher));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create a focus tracker");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mCommandDispatcher = new nsXULCommandDispatcher(this);
|
||||
NS_ENSURE_TRUE(mCommandDispatcher, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// this _could_ fail; e.g., if we've tried to grab the local store
|
||||
// before profiles have initialized. If so, no big deal; nothing
|
||||
|
|
Загрузка…
Ссылка в новой задаче