diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 1a19cb945aa6..bcfb9dca43b4 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -46,7 +46,6 @@ #include "jsnum.h" #include "nsAString.h" #include "nsIStatefulFrame.h" -#include "nsIPref.h" #include "nsINodeInfo.h" #include "nsNodeInfoManager.h" #include "nsContentList.h" @@ -60,6 +59,7 @@ #include "nsTArray.h" #include "nsTextFragment.h" #include "nsReadableUtils.h" +#include "nsIPrefBranch2.h" struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error! @@ -84,7 +84,7 @@ class imgIDecoderObserver; class imgIRequest; class imgILoader; class imgICache; -class nsIPrefBranch; +class nsIPrefBranch2; class nsIImageLoadingContent; class nsIDOMHTMLFormElement; class nsIDOMDocument; @@ -100,7 +100,6 @@ class nsIScriptContext; class nsIRunnable; class nsIInterfaceRequestor; template class nsCOMArray; -class nsIPref; struct JSRuntime; class nsICaseConversion; class nsIUGenCategory; @@ -110,6 +109,7 @@ class nsPIDOMWindow; class nsPIDOMEventTarget; class nsIPresShell; class nsIXPConnectJSObjectHolder; +class nsPrefOldCallback; #ifdef MOZ_XTF class nsIXTFService; #endif @@ -118,6 +118,11 @@ class nsIBidiKeyboard; #endif class nsIMIMEHeaderParam; +#ifndef have_PrefChangedFunc_typedef +typedef int (*PR_CALLBACK PrefChangedFunc)(const char *, void *); +#define have_PrefChangedFunc_typedef +#endif + extern const char kLoadAsData[]; enum EventNameType { @@ -559,7 +564,7 @@ public: void * aClosure); static void AddBoolPrefVarCache(const char* aPref, PRBool* aVariable); static void AddIntPrefVarCache(const char* aPref, PRInt32* aVariable); - static nsIPrefBranch *GetPrefBranch() + static nsIPrefBranch2 *GetPrefBranch() { return sPrefBranch; } @@ -1537,9 +1542,9 @@ private: static nsIXTFService *sXTFService; #endif - static nsIPrefBranch *sPrefBranch; - - static nsIPref *sPref; + static nsIPrefBranch2 *sPrefBranch; + // For old compatibility of RegisterPrefCallback + static nsCOMArray *sPrefCallbackList; static imgILoader* sImgLoader; static imgICache* sImgCache; diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 1e50749526db..ac5488a090ac 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -48,7 +48,7 @@ #include "nsPrintfCString.h" #include "nsUnicharUtils.h" #include "nsIPrefService.h" -#include "nsIPrefBranch.h" +#include "nsIPrefBranch2.h" #include "nsIPrefLocalizedString.h" #include "nsServiceManagerUtils.h" #include "nsIScriptGlobalObject.h" @@ -198,8 +198,7 @@ nsIIOService *nsContentUtils::sIOService; #ifdef MOZ_XTF nsIXTFService *nsContentUtils::sXTFService = nsnull; #endif -nsIPrefBranch *nsContentUtils::sPrefBranch = nsnull; -nsIPref *nsContentUtils::sPref = nsnull; +nsIPrefBranch2 *nsContentUtils::sPrefBranch = nsnull; imgILoader *nsContentUtils::sImgLoader; imgICache *nsContentUtils::sImgCache; nsIConsoleService *nsContentUtils::sConsoleService; @@ -231,6 +230,8 @@ JSRuntime *nsAutoGCRoot::sJSScriptRuntime; PRBool nsContentUtils::sInitialized = PR_FALSE; +nsCOMArray *nsContentUtils::sPrefCallbackList = nsnull; + static PLDHashTable sEventListenerManagersHash; class EventListenerManagerMapEntry : public PLDHashEntryHdr @@ -280,6 +281,43 @@ class nsSameOriginChecker : public nsIChannelEventSink, NS_DECL_NSIINTERFACEREQUESTOR }; +// For nsContentUtils::RegisterPrefCallback/UnregisterPrefCallback +class nsPrefOldCallback : public nsIObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + +public: + nsPrefOldCallback(const char *aPref, PrefChangedFunc aCallback, void *aClosure) : mPref(aPref), mCallback(aCallback), mClosure(aClosure) { + } + + PRBool IsEqual(const char *aPref, PrefChangedFunc aCallback, void *aClosure) { + return aCallback == mCallback && + aClosure == mClosure && + mPref.Equals(aPref); + } + +public: + nsCString mPref; + PrefChangedFunc mCallback; + void *mClosure; +}; + +NS_IMPL_ISUPPORTS1(nsPrefOldCallback, nsIObserver) + +NS_IMETHODIMP +nsPrefOldCallback::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) +{ + NS_ASSERTION(!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID), + "invalid topic"); + mCallback(NS_LossyConvertUTF16toASCII(aData).get(), mClosure); + + return NS_OK; +} + // static nsresult nsContentUtils::Init() @@ -297,9 +335,6 @@ nsContentUtils::Init() // It's ok to not have a pref service. CallGetService(NS_PREFSERVICE_CONTRACTID, &sPrefBranch); - // It's ok to not have prefs too. - CallGetService(NS_PREF_CONTRACTID, &sPref); - rv = NS_GetNameSpaceManager(&sNameSpaceManager); NS_ENSURE_SUCCESS(rv, rv); @@ -886,6 +921,20 @@ nsContentUtils::Shutdown() PRUint32 i; for (i = 0; i < PropertiesFile_COUNT; ++i) NS_IF_RELEASE(sStringBundles[i]); + + // Clean up c-style's observer + if (sPrefCallbackList) { + while (sPrefCallbackList->Count() > 0) { + nsCOMPtr callback = (*sPrefCallbackList)[0]; + NS_ABORT_IF_FALSE(callback, "Invalid c-style callback is appended"); + if (sPrefBranch) + sPrefBranch->RemoveObserver(callback->mPref.get(), callback); + sPrefCallbackList->RemoveObject(callback); + } + delete sPrefCallbackList; + sPrefCallbackList = nsnull; + } + NS_IF_RELEASE(sStringBundleService); NS_IF_RELEASE(sConsoleService); NS_IF_RELEASE(sDOMScriptObjectFactory); @@ -906,7 +955,6 @@ nsContentUtils::Shutdown() NS_IF_RELEASE(sImgLoader); NS_IF_RELEASE(sImgCache); NS_IF_RELEASE(sPrefBranch); - NS_IF_RELEASE(sPref); #ifdef IBMBIDI NS_IF_RELEASE(sBidiKeyboard); #endif @@ -2578,14 +2626,32 @@ nsContentUtils::GetStringPref(const char *aPref) return result; } +// RegisterPrefCallback/UnregisterPrefCallback are backward compatiblity for +// c-style observer. + // static void nsContentUtils::RegisterPrefCallback(const char *aPref, PrefChangedFunc aCallback, void * aClosure) { - if (sPref) - sPref->RegisterCallback(aPref, aCallback, aClosure); + if (sPrefBranch) { + if (!sPrefCallbackList) { + sPrefCallbackList = new nsCOMArray (); + if (!sPrefCallbackList) + return; + } + + nsPrefOldCallback *callback = new nsPrefOldCallback(aPref, aCallback, aClosure); + if (callback) { + if (NS_SUCCEEDED(sPrefBranch->AddObserver(aPref, callback, PR_FALSE))) { + sPrefCallbackList->AppendObject(callback); + return; + } + // error to get/add nsIPrefBranch2. Destroy callback information + delete callback; + } + } } // static @@ -2594,8 +2660,20 @@ nsContentUtils::UnregisterPrefCallback(const char *aPref, PrefChangedFunc aCallback, void * aClosure) { - if (sPref) - sPref->UnregisterCallback(aPref, aCallback, aClosure); + if (sPrefBranch) { + if (!sPrefCallbackList) + return; + + int i; + for (i = 0; i < sPrefCallbackList->Count(); i++) { + nsCOMPtr callback = (*sPrefCallbackList)[i]; + if (callback && callback->IsEqual(aPref, aCallback, aClosure)) { + sPrefBranch->RemoveObserver(aPref, callback); + sPrefCallbackList->RemoveObject(callback); + return; + } + } + } } static int diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index eaddcf8fec08..6d6655aca826 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -787,8 +787,7 @@ nsEventStateManager::Init() observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE); - nsCOMPtr prefBranch = - do_QueryInterface(nsContentUtils::GetPrefBranch()); + nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch(); if (prefBranch) { if (sESMInstanceCount == 1) { @@ -867,8 +866,7 @@ nsEventStateManager::~nsEventStateManager() nsresult nsEventStateManager::Shutdown() { - nsCOMPtr prefBranch = - do_QueryInterface(nsContentUtils::GetPrefBranch()); + nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch(); if (prefBranch) { prefBranch->RemoveObserver("accessibility.accesskeycausesactivation", this); diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index be43c3d3e9b7..e7ba7a6af1bf 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -158,8 +158,7 @@ nsFocusManager::nsFocusManager() nsFocusManager::~nsFocusManager() { - nsCOMPtr prefBranch = - do_QueryInterface(nsContentUtils::GetPrefBranch()); + nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch(); if (prefBranch) { prefBranch->RemoveObserver("accessibility.browsewithcaret", this); @@ -180,8 +179,7 @@ nsFocusManager::Init() nsContentUtils::GetBoolPref("accessibility.tabfocus_applies_to_xul", nsIContent::sTabFocusModelAppliesToXUL); - nsCOMPtr prefBranch = - do_QueryInterface(nsContentUtils::GetPrefBranch()); + nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch(); prefBranch->AddObserver("accessibility.browsewithcaret", fm, PR_TRUE); prefBranch->AddObserver("accessibility.tabfocus_applies_to_xul", fm, PR_TRUE); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index d31895456b43..ad5e423df341 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -79,6 +79,7 @@ #include "nsDisplayList.h" #include "nsBidiUtils.h" #include "nsFrameManager.h" +#include "nsIPrefService.h" //---------------------------------------------------------------------- diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 73bbc40b97d9..44da624a5327 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1758,8 +1758,7 @@ static const char kIconLoadPrefs[][40] = { nsImageFrame::IconLoad::IconLoad() { - nsCOMPtr prefBranch = - do_QueryInterface(nsContentUtils::GetPrefBranch()); + nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch(); // register observers for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(kIconLoadPrefs); ++i)