diff --git a/mozilla/embedding/components/commandhandler/src/nsCommandManager.cpp b/mozilla/embedding/components/commandhandler/src/nsCommandManager.cpp index 5856aa2daa8..93f2536f959 100644 --- a/mozilla/embedding/components/commandhandler/src/nsCommandManager.cpp +++ b/mozilla/embedding/components/commandhandler/src/nsCommandManager.cpp @@ -53,7 +53,7 @@ #include "nsIDOMWindowInternal.h" #include "nsIFocusController.h" -#include "nsSupportsArray.h" +#include "nsCOMArray.h" #include "nsCommandManager.h" @@ -70,30 +70,27 @@ nsCommandManager::~nsCommandManager() } -PR_STATIC_CALLBACK(PRBool) -TraverseCommandObservers(nsHashKey *aKey, void *aData, void* aClosure) +PR_STATIC_CALLBACK(PLDHashOperator) +TraverseCommandObservers(const char* aKey, nsCOMArray* aObservers, + void* aClosure) { - nsISupportsArray *observers = NS_STATIC_CAST(nsISupportsArray*, aData); nsCycleCollectionTraversalCallback *cb = NS_STATIC_CAST(nsCycleCollectionTraversalCallback*, aClosure); - PRUint32 i, numItems; - nsresult rv = observers->Count(&numItems); - NS_ENSURE_SUCCESS(rv, kHashEnumerateStop); - + PRInt32 i, numItems = aObservers->Count(); for (i = 0; i < numItems; ++i) { - cb->NoteXPCOMChild(observers->ElementAt(i)); + cb->NoteXPCOMChild(aObservers->ObjectAt(i)); } - return kHashEnumerateNext; + return PL_DHASH_NEXT; } NS_IMPL_CYCLE_COLLECTION_CLASS(nsCommandManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCommandManager) - tmp->mCommandObserversTable.Reset(); + tmp->mObserversTable.Clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCommandManager) - tmp->mCommandObserversTable.Enumerate(TraverseCommandObservers, &cb); + tmp->mObserversTable.EnumerateRead(TraverseCommandObservers, &cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsCommandManager, nsICommandManager) @@ -126,31 +123,22 @@ nsCommandManager::Init(nsIDOMWindow *aWindow) NS_IMETHODIMP nsCommandManager::CommandStatusChanged(const char * aCommandName) { - nsCStringKey hashKey(aCommandName); + nsCOMArray* commandObservers; + mObserversTable.Get(aCommandName, &commandObservers); - - nsresult rv = NS_OK; - nsCOMPtr commandSupports = getter_AddRefs(mCommandObserversTable.Get(&hashKey)); - nsCOMPtr commandObservers = do_QueryInterface(commandSupports); - if (commandObservers) - { - PRUint32 numItems; - rv = commandObservers->Count(&numItems); - if (NS_FAILED(rv)) return rv; - - for (PRUint32 i = 0; i < numItems; i ++) - { - nsCOMPtr itemSupports; - rv = commandObservers->GetElementAt(i, getter_AddRefs(itemSupports)); - if (NS_FAILED(rv)) break; - nsCOMPtr itemObserver = do_QueryInterface(itemSupports); - if (itemObserver) - { - // should we get the command state to pass here? This might be expensive. - itemObserver->Observe((nsICommandManager *)this, aCommandName,NS_LITERAL_STRING("command_status_changed").get()); - } - } - } + if (commandObservers) + { + // XXX Should we worry about observers removing themselves from Observe()? + PRInt32 i, numItems = commandObservers->Count(); + for (i = 0; i < numItems; ++i) + { + nsCOMPtr observer = commandObservers->ObjectAt(i); + // should we get the command state to pass here? This might be expensive. + observer->Observe(NS_ISUPPORTS_CAST(nsICommandManager*, this), + aCommandName, + NS_LITERAL_STRING("command_status_changed").get()); + } + } return NS_OK; } @@ -163,32 +151,27 @@ nsCommandManager::CommandStatusChanged(const char * aCommandName) NS_IMETHODIMP nsCommandManager::AddCommandObserver(nsIObserver *aCommandObserver, const char *aCommandToObserve) { - NS_ENSURE_ARG(aCommandObserver); - - nsresult rv = NS_OK; + NS_ENSURE_ARG(aCommandObserver); - // XXX todo: handle special cases of aCommandToObserve being null, or empty - - // for each command in the table, we make a list of observers for that command - nsCStringKey hashKey(aCommandToObserve); - - nsCOMPtr commandSupports = getter_AddRefs(mCommandObserversTable.Get(&hashKey)); - nsCOMPtr commandObservers = do_QueryInterface(commandSupports); - if (!commandObservers) - { - rv = NS_NewISupportsArray(getter_AddRefs(commandObservers)); - if (NS_FAILED(rv)) return rv; - - commandSupports = do_QueryInterface(commandObservers); - rv = mCommandObserversTable.Put(&hashKey, commandSupports); - if (NS_FAILED(rv)) return rv; - } - - // need to check that this command observer hasn't already been registered - nsCOMPtr observerAsSupports = do_QueryInterface(aCommandObserver); - PRInt32 existingIndex = commandObservers->IndexOf(observerAsSupports); + nsresult rv = NS_OK; + + // XXX todo: handle special cases of aCommandToObserve being null, or empty + + // for each command in the table, we make a list of observers for that command + nsCOMArray* commandObservers; + if (!mObserversTable.Get(aCommandToObserve, &commandObservers)) + { + nsAutoPtr > array(new nsCOMArray); + if (!array || !mObserversTable.Put(aCommandToObserve, array)) + return NS_ERROR_OUT_OF_MEMORY; + + commandObservers = array.forget(); + } + + // need to check that this command observer hasn't already been registered + PRInt32 existingIndex = commandObservers->IndexOf(aCommandObserver); if (existingIndex == -1) - rv = commandObservers->AppendElement(observerAsSupports); + rv = commandObservers->AppendObject(aCommandObserver); else NS_WARNING("Registering command observer twice on the same command"); @@ -199,19 +182,16 @@ nsCommandManager::AddCommandObserver(nsIObserver *aCommandObserver, const char * NS_IMETHODIMP nsCommandManager::RemoveCommandObserver(nsIObserver *aCommandObserver, const char *aCommandObserved) { - NS_ENSURE_ARG(aCommandObserver); + NS_ENSURE_ARG(aCommandObserver); - // XXX todo: handle special cases of aCommandToObserve being null, or empty - nsCStringKey hashKey(aCommandObserved); + // XXX todo: handle special cases of aCommandToObserve being null, or empty - nsCOMPtr commandSupports = getter_AddRefs(mCommandObserversTable.Get(&hashKey)); - nsCOMPtr commandObservers = do_QueryInterface(commandSupports); - if (!commandObservers) - return NS_ERROR_UNEXPECTED; - - nsCOMPtr observerAsSupports = do_QueryInterface(aCommandObserver); - nsresult removed = commandObservers->RemoveElement(observerAsSupports); - return (removed) ? NS_OK : NS_ERROR_FAILURE; + nsCOMArray* commandObservers; + if (!mObserversTable.Get(aCommandObserved, &commandObservers)) + return NS_ERROR_UNEXPECTED; + + return commandObservers->RemoveObject(aCommandObserver) ? NS_OK : + NS_ERROR_FAILURE; } /* boolean isCommandSupported(in string aCommandName, diff --git a/mozilla/embedding/components/commandhandler/src/nsCommandManager.h b/mozilla/embedding/components/commandhandler/src/nsCommandManager.h index b7fe6e6dec7..69b79fbd0ec 100644 --- a/mozilla/embedding/components/commandhandler/src/nsCommandManager.h +++ b/mozilla/embedding/components/commandhandler/src/nsCommandManager.h @@ -41,7 +41,7 @@ #include "nsString.h" -#include "nsHashtable.h" +#include "nsClassHashtable.h" #include "nsWeakReference.h" #include "nsICommandManager.h" @@ -49,7 +49,7 @@ #include "nsCycleCollectionParticipant.h" class nsIController; - +template class nsCOMArray; class nsCommandManager : public nsICommandManager, @@ -84,7 +84,7 @@ protected: protected: - nsSupportsHashtable mCommandObserversTable; // hash table of nsIObservers, keyed by command name + nsClassHashtable > mObserversTable; nsIDOMWindow* mWindow; // weak ptr. The window should always outlive us };