Fix for bug 103883. Add weak ref support for prefs observers to help reduce MLK cycles with preferences. r=ccarlen, darin, gordon, hewitt, mstoltz, srilatha, sspitzer. sr=alecf.

git-svn-id: svn://10.0.0.236/trunk@105960 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bnesse%netscape.com
2001-10-22 20:54:48 +00:00
parent 7423f3c016
commit 7f9fa9521d
20 changed files with 433 additions and 308 deletions

View File

@@ -85,7 +85,6 @@ static NS_DEFINE_IID(kIIOServiceIID, NS_IIOSERVICE_IID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_IID(kIStringBundleServiceIID, NS_ISTRINGBUNDLESERVICE_IID);
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREFSERVICE_CID);
static NS_DEFINE_CID(kCScriptNameSetRegistryCID,
NS_SCRIPT_NAMESET_REGISTRY_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
@@ -2426,8 +2425,8 @@ nsScriptSecurityManager::InitPrefs()
// Set the initial value of the "javascript.enabled" prefs
JSEnabledPrefChanged(securityPref);
// set observer callbacks in case the value of the pref changes
prefBranchInternal->AddObserver(sJSEnabledPrefName, this);
prefBranchInternal->AddObserver(sJSMailEnabledPrefName, this);
prefBranchInternal->AddObserver(sJSEnabledPrefName, this, PR_FALSE);
prefBranchInternal->AddObserver(sJSMailEnabledPrefName, this, PR_FALSE);
PRUint32 prefCount;
char** prefNames;
@@ -2440,7 +2439,7 @@ nsScriptSecurityManager::InitPrefs()
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
}
//-- Set a callback for policy changes
prefBranchInternal->AddObserver(sPolicyPrefix, this);
prefBranchInternal->AddObserver(sPolicyPrefix, this, PR_FALSE);
//-- Initialize the principals database from prefs
rv = prefBranch->GetChildList(sPrincipalPrefix, &prefCount, &prefNames);
@@ -2451,7 +2450,7 @@ nsScriptSecurityManager::InitPrefs()
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(prefCount, prefNames);
}
//-- Set a callback for principal changes
prefBranchInternal->AddObserver(sPrincipalPrefix, this);
prefBranchInternal->AddObserver(sPrincipalPrefix, this, PR_FALSE);
return NS_OK;
}

View File

@@ -47,7 +47,7 @@
//////////// global constants ////////////////////
const nsIPref = Components.interfaces.nsIPref;
const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
////////////////////////////////////////////////////////////////////////////
//// class PrefUtils
@@ -58,35 +58,40 @@ var PrefUtils =
init: function()
{
this.mPrefs = XPCU.getService("@mozilla.org/preferences;1", "nsIPref");
var prefService = XPCU.getService("@mozilla.org/preferences-service;1", "nsIPrefService");
this.mPrefs = prefService.getBranch(null);
},
addObserver: function(aDomain, aFunction)
{
if (!this.mPrefs) this.init();
this.mPrefs.addObserver(aDomain, aFunction);
var pbi = XPCU.QI(this.mPrefs, "nsIPrefBranchInternal");
if (pbi)
pbi.addObserver(aDomain, aFunction, false);
},
removeObserver: function(aDomain, aFunction)
{
if (!this.mPrefs) this.init();
this.mPrefs.removeObserver(aDomain, aFunction);
var pbi = XPCU.QI(this.mPrefs, "nsIPrefBranchInternal");
if (pbi)
pbi.removeObserver(aDomain, aFunction);
},
setPref: function(aName, aValue)
{
if (!this.mPrefs) this.init();
var type = this.mPrefs.GetPrefType(aName);
var type = this.mPrefs.getPrefType(aName);
try {
if (type == nsIPref.ePrefString) {
this.mPrefs.SetUnicharPref(aName, aValue);
} else if (type == nsIPref.ePrefBool) {
this.mPrefs.SetBoolPref(aName, aValue);
} else if (type == nsIPref.ePrefInt) {
this.mPrefs.SetIntPref(aName, aValue);
if (type == nsIPrefBranch.PREF_STRING) {
this.mPrefs.setComplexValue(aName, Components.interfaces.nsISupportsWString, aValue);
} else if (type == nsIPrefBranch.PREF_BOOL) {
this.mPrefs.setBoolPref(aName, aValue);
} else if (type == nsIPrefBranch.PREF_INT) {
this.mPrefs.setIntPref(aName, aValue);
}
} catch(ex) {
debug("ERROR: Unable to write pref \"" + aName + "\".\n");
@@ -97,14 +102,14 @@ var PrefUtils =
{
if (!this.mPrefs) this.init();
var type = this.mPrefs.GetPrefType(aName);
var type = this.mPrefs.getPrefType(aName);
try {
if (type == nsIPref.ePrefString) {
return this.mPrefs.CopyUnicharPref(aName);
} else if (type == nsIPref.ePrefBool) {
return this.mPrefs.GetBoolPref(aName);
} else if (type == nsIPref.ePrefInt) {
return this.mPrefs.GetIntPref(aName);
if (type == nsIPrefBranch.PREF_STRING) {
return this.mPrefs.getComplexValue(aName, Components.interfaces.nsISupportsWString);
} else if (type == nsIPrefBranch.PREF_BOOL) {
return this.mPrefs.getBoolPref(aName);
} else if (type == nsIPrefBranch.PREF_INT) {
return this.mPrefs.getIntPref(aName);
}
} catch(ex) {
debug("ERROR: Unable to read pref \"" + aName + "\".\n");

View File

@@ -28,7 +28,6 @@ const kObserverServiceIID = "@mozilla.org/observer-service;1";
const kDirServiceCID = "@mozilla.org/file/directory_service;1"
var gNavigator = window._content;
const nsIPref = Components.interfaces.nsIPref;
//////////////////////////////////////////////////
@@ -75,7 +74,7 @@ InspectorSidebar.prototype =
this.loadViewerRegistry();
this.installNavObserver();
this.initPrefs();
PrefUtils.addObserver("inspector", PrefChangeObserver);
this.setFlashSelected(PrefUtils.getPref("inspector.blink.on"));
},
@@ -166,6 +165,7 @@ InspectorSidebar.prototype =
exit: function()
{
window.close()
PrefUtils.removeObserver("inspector", PrefChangeObserver);
},
////////////////////////////////////////////////////////////////////////////
@@ -228,44 +228,6 @@ InspectorSidebar.prototype =
////////////////////////////////////////////////////////////////////////////
//// Preferences
initPrefs: function()
{
this.mPrefs = XPCU.getService("@mozilla.org/preferences;1", "nsIPref");
this.mPrefs.addObserver("inspector", PrefChangeObserver);
},
setPref: function(aName, aValue)
{
var type = this.mPrefs.GetPrefType(aName);
try {
if (type == nsIPref.ePrefString) {
this.mPrefs.SetUnicharPref(aName, aValue);
} else if (type == nsIPref.ePrefBool) {
this.mPrefs.SetBoolPref(aName, aValue);
} else if (type == nsIPref.ePrefInt) {
this.mPrefs.SetIntPref(aName, aValue);
}
} catch(ex) {
debug("ERROR: Unable to write pref \"" + aName + "\".\n");
}
},
getPref: function(aName)
{
var type = this.mPrefs.GetPrefType(aName);
try {
if (type == nsIPref.ePrefString) {
return this.mPrefs.CopyUnicharPref(aName);
} else if (type == nsIPref.ePrefBool) {
return this.mPrefs.GetBoolPref(aName);
} else if (type == nsIPref.ePrefInt) {
return this.mPrefs.GetIntPref(aName);
}
} catch(ex) {
debug("ERROR: Unable to read pref \"" + aName + "\".\n");
}
},
onPrefChanged: function(aName)
{
if (aName == "inspector.blink.on")

View File

@@ -74,18 +74,8 @@ const DEBUG = false;
var other_header = "";
var sendFormat = msgCompSendFormat.AskUser;
var prefs = Components.classes["@mozilla.org/preferences;1"].getService();
if (prefs) {
prefs = prefs.QueryInterface(Components.interfaces.nsIPref);
if (prefs) {
try {
other_header = prefs.CopyCharPref("mail.compose.other.header");
}
catch (ex) {
dump("failed to get the mail.compose.other.header pref\n");
}
}
}
var prefs = null;
var gPrefBranchInternal = null;
function disableEditableFields()
{
@@ -619,41 +609,43 @@ var directoryServerObserver = {
function AddDirectoryServerObserver(flag) {
if (flag) {
prefs.addObserver("ldap_2.autoComplete.useDirectory", directoryServerObserver, false);
prefs.addObserver("ldap_2.autoComplete.directoryServer", directoryServerObserver, false);
gPrefBranchInternal.addObserver("ldap_2.autoComplete.useDirectory",
directoryServerObserver, false);
gPrefBranchInternal.addObserver("ldap_2.autoComplete.directoryServer",
directoryServerObserver, false);
}
else
{
var prefstring = "mail.identity." + gCurrentIdentity.key + ".overrideGlobal_Pref";
prefs.addObserver(prefstring, directoryServerObserver, false);
gPrefBranchInternal.addObserver(prefstring, directoryServerObserver, false);
prefstring = "mail.identity." + gCurrentIdentity.key + ".directoryServer";
prefs.addObserver(prefstring, directoryServerObserver, false);
gPrefBranchInternal.addObserver(prefstring, directoryServerObserver, false);
}
}
function RemoveDirectoryServerObserver(prefstring)
{
if (!prefstring) {
prefs.removeObserver("ldap_2.autoComplete.useDirectory", directoryServerObserver);
prefs.removeObserver("ldap_2.autoComplete.directoryServer", directoryServerObserver);
gPrefBranchInternal.removeObserver("ldap_2.autoComplete.useDirectory", directoryServerObserver);
gPrefBranchInternal.removeObserver("ldap_2.autoComplete.directoryServer", directoryServerObserver);
}
else
{
var str = prefstring + ".overrideGlobal_Pref";
prefs.removeObserver(str, directoryServerObserver);
gPrefBranchInternal.removeObserver(str, directoryServerObserver);
str = prefstring + ".directoryServer";
prefs.removeObserver(str, directoryServerObserver);
gPrefBranchInternal.removeObserver(str, directoryServerObserver);
}
}
function AddDirectorySettingsObserver()
{
prefs.addObserver(currentAutocompleteDirectory, directoryServerObserver, false);
gPrefBranchInternal.addObserver(currentAutocompleteDirectory, directoryServerObserver, false);
}
function RemoveDirectorySettingsObserver(prefstring)
{
prefs.removeObserver(prefstring, directoryServerObserver);
gPrefBranchInternal.removeObserver(prefstring, directoryServerObserver);
}
function setupLdapAutocompleteSession()
@@ -663,9 +655,9 @@ function setupLdapAutocompleteSession()
var prevAutocompleteDirectory = currentAutocompleteDirectory;
var i;
autocompleteLdap = prefs.GetBoolPref("ldap_2.autoComplete.useDirectory");
autocompleteLdap = prefs.getBoolPref("ldap_2.autoComplete.useDirectory");
if (autocompleteLdap)
autocompleteDirectory = prefs.CopyCharPref(
autocompleteDirectory = prefs.getCharPref(
"ldap_2.autoComplete.directoryServer");
if(gCurrentIdentity.overrideGlobalPref) {
@@ -709,7 +701,7 @@ function setupLdapAutocompleteSession()
Components.interfaces.nsILDAPURL);
try {
serverURL.spec = prefs.CopyCharPref(autocompleteDirectory +
serverURL.spec = prefs.getCharPref(autocompleteDirectory +
".uri");
} catch (ex) {
dump("ERROR: " + ex + "\n");
@@ -719,7 +711,7 @@ function setupLdapAutocompleteSession()
// don't search on non-CJK strings shorter than this
//
try {
LDAPSession.minStringLength = prefs.GetIntPref(
LDAPSession.minStringLength = prefs.getIntPref(
autocompleteDirectory + ".autoComplete.minStringLength");
} catch (ex) {
// if this pref isn't there, no big deal. just let
@@ -729,7 +721,7 @@ function setupLdapAutocompleteSession()
// don't search on CJK strings shorter than this
//
try {
LDAPSession.cjkMinStringLength = prefs.GetIntPref(
LDAPSession.cjkMinStringLength = prefs.getIntPref(
autocompleteDirectory + ".autoComplete.cjkMinStringLength");
} catch (ex) {
// if this pref isn't there, no big deal. just let
@@ -747,8 +739,9 @@ function setupLdapAutocompleteSession()
//
try {
ldapFormatter.nameFormat =
prefs.CopyUnicharPref(autocompleteDirectory +
".autoComplete.nameFormat");
prefs.getComplexValue(autocompleteDirectory +
".autoComplete.nameFormat",
Components.interfaces.nsISupportsWString);
} catch (ex) {
// if this pref isn't there, no big deal. just let
// nsAbLDAPAutoCompFormatter use its default.
@@ -758,8 +751,9 @@ function setupLdapAutocompleteSession()
//
try {
ldapFormatter.addressFormat =
prefs.CopyUnicharPref(autocompleteDirectory +
".autoComplete.addressFormat");
prefs.getComplexValue(autocompleteDirectory +
".autoComplete.addressFormat",
Components.interfaces.nsISupportsWString);
} catch (ex) {
// if this pref isn't there, no big deal. just let
// nsAbLDAPAutoCompFormatter use its default.
@@ -773,7 +767,7 @@ function setupLdapAutocompleteSession()
// 2 = other per-addressbook format
//
var showComments = 0;
showComments = prefs.GetIntPref(
showComments = prefs.getIntPref(
"mail.autoComplete.commentColumn");
switch (showComments) {
@@ -781,8 +775,9 @@ function setupLdapAutocompleteSession()
case 1:
// use the name of this directory
//
ldapFormatter.commentFormat = prefs.CopyUnicharPref(
autocompleteDirectory + ".description");
ldapFormatter.commentFormat = prefs.getComplexValue(
autocompleteDirectory + ".description",
Components.interfaces.nsISupportsWString);
break;
case 2:
@@ -790,9 +785,9 @@ function setupLdapAutocompleteSession()
//
try {
ldapFormatter.commentFormat =
prefs.CopyUnicharPref(autocompleteDirectory +
".autoComplete.commentFormat");
prefs.getComplexValue(autocompleteDirectory +
".autoComplete.commentFormat",
Components.interfaces.nsISupportsWString);
} catch (innerException) {
// if nothing has been specified, use the ldap
// organization field
@@ -820,8 +815,10 @@ function setupLdapAutocompleteSession()
//
try {
LDAPSession.outputFormat =
prefs.CopyUnicharPref(autocompleteDirectory +
".autoComplete.outputFormat");
prefs.getComplexValue(autocompleteDirectory +
".autoComplete.outputFormat",
Components.interfaces.nsISupportsWString);
} catch (ex) {
// if this pref isn't there, no big deal. just let
// nsLDAPAutoCompleteSession use its default.
@@ -830,8 +827,10 @@ function setupLdapAutocompleteSession()
// override default search filter template?
//
try {
LDAPSession.filterTemplate = prefs.CopyUnicharPref(
autocompleteDirectory + ".autoComplete.filterTemplate");
LDAPSession.filterTemplate = prefs.getComplexValue(
autocompleteDirectory + ".autoComplete.filterTemplate",
Components.interfaces.nsISupportsWString);
} catch (ex) {
// if this pref isn't there, no big deal. just let
// nsLDAPAutoCompleteSession use its default
@@ -844,7 +843,7 @@ function setupLdapAutocompleteSession()
// but there's no UI for that yet
//
LDAPSession.maxHits =
prefs.GetIntPref(autocompleteDirectory + ".maxHits");
prefs.getIntPref(autocompleteDirectory + ".maxHits");
} catch (ex) {
// if this pref isn't there, or is out of range, no big deal.
// just let nsLDAPAutoCompleteSession use its default.
@@ -1186,6 +1185,24 @@ function WizCallback(state)
function ComposeLoad()
{
// First get the preferences service
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
prefs = prefService.getBranch(null);
gPrefBranchInternal = prefs.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
}
catch (ex) {
dump("failed to preferences services\n");
}
try {
other_header = prefs.getCharPref("mail.compose.other.header");
}
catch (ex) {
dump("failed to get the mail.compose.other.header pref\n");
}
AddMessageComposeOfflineObserver();
AddDirectoryServerObserver(true);
@@ -1261,7 +1278,8 @@ function SetDocumentCharacterSet(aCharset)
function UpdateMailEditCharset()
{
var send_default_charset = prefs.getLocalizedUnicharPref("mailnews.send_default_charset");
var send_default_charset = prefs.getComplexValue("mailnews.send_default_charset",
Components.interfaces.nsIPrefLocalizedString);
// dump("send_default_charset is " + send_default_charset + "\n");
var compFieldsCharset = msgCompose.compFields.characterSet;
@@ -1306,7 +1324,8 @@ function GetCharsetUIString()
{
var charset = msgCompose.compFields.characterSet;
if (g_send_default_charset == null) {
g_send_default_charset = prefs.getLocalizedUnicharPref("mailnews.send_default_charset");
g_send_default_charset = prefs.getComplexValue("mailnews.send_default_charset",
Components.interfaces.nsIPrefLocalizedString);
}
charset = charset.toUpperCase();
@@ -1378,7 +1397,7 @@ function GenericSendMessage( msgType )
if (msgType == msgCompDeliverMode.Now || msgType == msgCompDeliverMode.Later)
{
//Do we need to check the spelling?
if (prefs.GetBoolPref("mail.SpellCheckBeforeSend"))
if (prefs.getBoolPref("mail.SpellCheckBeforeSend"))
goDoCommand('cmd_spelling');
//Check if we have a subject, else ask user for confirmation
@@ -1477,7 +1496,7 @@ function SendMessage()
function SendMessageWithCheck()
{
var warn = prefs.GetBoolPref("mail.warn_on_send_accel_key");
var warn = prefs.getBoolPref("mail.warn_on_send_accel_key");
if (warn) {
var buttonPressed = {value:1};
@@ -1499,7 +1518,7 @@ function SendMessageWithCheck()
return;
}
if (checkValue.value) {
prefs.SetBoolPref("mail.warn_on_send_accel_key", false);
prefs.setBoolPref("mail.warn_on_send_accel_key", false);
}
}
@@ -2073,7 +2092,7 @@ function DetermineHTMLAction(convertible)
default :
//See if a preference has been set to tell us what to do. Note that we do not honor that
//preference for newsgroups. Only for e-mail addresses.
var action = prefs.GetIntPref("mail.default_html_action");
var action = prefs.getIntPref("mail.default_html_action");
switch (action)
{
case msgCompSendFormat.PlainText :
@@ -2203,7 +2222,7 @@ function setupAutocomplete()
// honor it as well
//
try {
if (prefs.GetIntPref("mail.autoComplete.commentColumn")) {
if (prefs.getIntPref("mail.autoComplete.commentColumn")) {
document.getElementById('msgRecipient#1').showCommentColumn =
true;
}

View File

@@ -40,7 +40,10 @@
#include "nsDBFolderInfo.h"
#include "nsMsgDatabase.h"
#include "nsMsgFolderFlags.h"
#include "nsIPref.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPrefLocalizedString.h"
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsObserverService.h"
@@ -99,32 +102,41 @@ NS_IMETHODIMP nsFolderCharsetObserver::Observe(nsISupports *aSubject, const char
{
nsresult rv;
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIPrefBranch> prefBranch;
rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
NS_ENSURE_SUCCESS(rv, rv);
if (!nsCRT::strcmp(aTopic, "nsPref:changed"))
if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID))
{
nsDependentString prefName(someData);
if (prefName.Equals(NS_LITERAL_STRING(kMAILNEWS_VIEW_DEFAULT_CHARSET)))
{
PRUnichar *prefCharset = nsnull;
rv = prefs->GetLocalizedUnicharPref(kMAILNEWS_VIEW_DEFAULT_CHARSET, &prefCharset);
if (NS_SUCCEEDED(rv))
{
gDefaultCharacterSet.Assign(prefCharset);
PR_Free(prefCharset);
nsCOMPtr<nsIPrefLocalizedString> pls;
rv = prefBranch->GetComplexValue(kMAILNEWS_VIEW_DEFAULT_CHARSET,
NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
if (NS_SUCCEEDED(rv)) {
nsXPIDLString ucsval;
pls->ToString(getter_Copies(ucsval));
if (ucsval)
gDefaultCharacterSet.Assign(ucsval.get());
}
}
else if (prefName.Equals(NS_LITERAL_STRING(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE)))
{
rv = prefs->GetBoolPref(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, &gDefaultCharacterOverride);
rv = prefBranch->GetBoolPref(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, &gDefaultCharacterOverride);
}
}
else if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
{
rv = prefs->RemoveObserver(kMAILNEWS_VIEW_DEFAULT_CHARSET, this);
rv = prefs->RemoveObserver(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, this);
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch);
if (pbi) {
rv = pbi->RemoveObserver(kMAILNEWS_VIEW_DEFAULT_CHARSET, this);
rv = pbi->RemoveObserver(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, this);
}
gReleaseObserver = PR_TRUE; // set true to release observer
}
@@ -185,17 +197,24 @@ nsDBFolderInfo::nsDBFolderInfo(nsMsgDatabase *mdb)
{
gInitializeObserver = PR_TRUE;
nsresult rv;
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
nsCOMPtr<nsIPrefBranch> prefBranch;
if (NS_SUCCEEDED(rv))
{
PRUnichar *prefCharset = nsnull;
rv = prefs->GetLocalizedUnicharPref(kMAILNEWS_VIEW_DEFAULT_CHARSET, &prefCharset);
if (NS_SUCCEEDED(rv))
{
gDefaultCharacterSet.Assign(prefCharset);
PR_Free(prefCharset);
rv = prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
}
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIPrefLocalizedString> pls;
rv = prefBranch->GetComplexValue(kMAILNEWS_VIEW_DEFAULT_CHARSET,
NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
if (NS_SUCCEEDED(rv)) {
nsXPIDLString ucsval;
pls->ToString(getter_Copies(ucsval));
if (ucsval)
gDefaultCharacterSet.Assign(ucsval.get());
}
rv = prefs->GetBoolPref(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, &gDefaultCharacterOverride);
rv = prefBranch->GetBoolPref(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, &gDefaultCharacterOverride);
gFolderCharsetObserver = new nsFolderCharsetObserver();
NS_ASSERTION(gFolderCharsetObserver, "failed to create observer");
@@ -204,8 +223,11 @@ nsDBFolderInfo::nsDBFolderInfo(nsMsgDatabase *mdb)
if (gFolderCharsetObserver)
{
NS_ADDREF(gFolderCharsetObserver);
rv = prefs->AddObserver(kMAILNEWS_VIEW_DEFAULT_CHARSET, gFolderCharsetObserver);
rv = prefs->AddObserver(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, gFolderCharsetObserver);
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch);
if (pbi) {
rv = pbi->AddObserver(kMAILNEWS_VIEW_DEFAULT_CHARSET, gFolderCharsetObserver, PR_FALSE);
rv = pbi->AddObserver(kMAILNEWS_DEFAULT_CHARSET_OVERRIDE, gFolderCharsetObserver, PR_FALSE);
}
// also register for shutdown
nsCOMPtr<nsIObserverService> observerService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);

View File

@@ -211,7 +211,7 @@ interface nsIPref : nsISupports {
* The observers have their |Observe| methods called with
* ([the observer], "nsPref:changed", [pref name]).
*/
void addObserver(in string aDomain, in nsIObserver aObserver);
void addObserver(in string aDomain, in nsIObserver aObserver, in boolean aHoldWeak);
void removeObserver(in string aDomain, in nsIObserver aObserver);

View File

@@ -65,14 +65,27 @@ interface nsIPrefBranchInternal : nsISupports
*
* @param aDomain The preference on which to listen for changes.
* @param aObserver The object to be notified if the preference changes.
* @param aHoldWeak true Hold a weak reference to |aObserver|. The object
* must implement the nsISupportsWeakReference
* interface or this will fail.
* false Hold a strong reference to |aObserver|.
*
* @note
* Registering as a preference observer can open an object to potential
* cyclical references which will cause memory leaks. These cycles generally
* occur because an object both registers itself as an observer (causing the
* branch to hold a reference to the observer) and holds a reference to the
* branch object for the purpose of getting/setting preference values. This
* should be addressed in the near future.
* branch object for the purpose of getting/setting preference values. There
* are 3 approaches which have been implemented in an attempt to avoid these
* situations.
* 1) The nsPrefBranch object supports nsISupportsWeakReference. Any consumer
* may hold a weak reference to it instead of a strong one.
* 2) The nsPrefBranch object listens for xpcom-shutdown and frees all of the
* objects currently in its observer list. This insures that long lived
* objects (services for example) will be freed correctly.
* 3) The observer can request to be held as a weak reference when it is
* registered. This insures that shorter lived objects (say one tied to an
* open window) will not fall into the cyclical reference trap.
*
* @return NS_OK The observer was successfully set.
* @return Other The observer could not be created.
@@ -80,7 +93,7 @@ interface nsIPrefBranchInternal : nsISupports
* @see nsIObserver
* @see removeObserver
*/
void addObserver(in string aDomain, in nsIObserver aObserver);
void addObserver(in string aDomain, in nsIObserver aObserver, in boolean aHoldWeak);
/**
* Called by a preferences consumer to remove itself from the preference
@@ -104,6 +117,6 @@ interface nsIPrefBranchInternal : nsISupports
/**
* Notification sent when a preference changes.
*/
#define NS_PREFBRANCH_PREFCHANGE_OBSERVER_ID "nsPref:changed"
#define NS_PREFBRANCH_PREFCHANGE_TOPIC_ID "nsPref:changed"
%}

View File

@@ -171,12 +171,12 @@ interface nsIPrefService : nsISupports
/**
* Notification sent before reading the default user preferences files.
*/
#define NS_PREFSERVICE_READ_OBSERVER_ID "prefservice:before-read-userprefs"
#define NS_PREFSERVICE_READ_TOPIC_ID "prefservice:before-read-userprefs"
/**
* Notification sent when resetPrefs has been called, but before the actual
* reset process occurs.
*/
#define NS_PREFSERVICE_RESET_OBSERVER_ID "prefservice:before-reset"
#define NS_PREFSERVICE_RESET_TOPIC_ID "prefservice:before-reset"
%}

View File

@@ -346,13 +346,13 @@ NS_IMETHODIMP nsPref::GetChildList(const char *aStartingAt, PRUint32 *aCount, ch
return rv;
}
NS_IMETHODIMP nsPref::AddObserver(const char *aDomain, nsIObserver *aObserver)
NS_IMETHODIMP nsPref::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak)
{
nsresult rv;
nsCOMPtr<nsIPrefBranchInternal> prefBranch = do_QueryInterface(mPrefService, &rv);
if (NS_SUCCEEDED(rv))
rv = prefBranch->AddObserver(aDomain, aObserver);
rv = prefBranch->AddObserver(aDomain, aObserver, aHoldWeak);
return rv;
}

View File

@@ -41,6 +41,7 @@
#include "nsILocalFile.h"
#include "nsIObserverService.h"
#include "nsISupportsPrimitives.h"
#include "nsObserverService.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsXPIDLString.h"
@@ -60,7 +61,8 @@ struct EnumerateData {
struct PrefCallbackData {
nsIPrefBranch *pBranch;
nsIObserver *pObserver;
nsISupports *pObserver;
PRBool bIsWeakRef;
};
@@ -112,36 +114,23 @@ nsPrefBranch::nsPrefBranch(const char *aPrefRoot, PRBool aDefaultBranch)
mPrefRoot = aPrefRoot;
mPrefRootLength = mPrefRoot.Length();
mIsDefault = aDefaultBranch;
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService) {
++mRefCnt; // Our refcnt must be > 0 when we call this, or we'll get deleted!
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
--mRefCnt;
}
}
nsPrefBranch::~nsPrefBranch()
{
PrefCallbackData *pCallback;
if (mObservers) {
// unregister the observers
PRInt32 count;
count = mObservers->Count();
if (count > 0) {
PRInt32 i;
nsCString domain;
for (i = 0; i < count; i++) {
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
if (pCallback) {
mObserverDomains.CStringAt(i, domain);
PREF_UnregisterCallback(domain, NotifyObserver, pCallback);
NS_RELEASE(pCallback->pObserver);
}
nsMemory::Free(pCallback);
}
// now empty the observer arrays in bulk
mObservers->Clear();
mObserverDomains.Clear();
}
delete mObservers;
}
freeObserverList();
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
if (observerService)
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
@@ -157,6 +146,7 @@ NS_INTERFACE_MAP_BEGIN(nsPrefBranch)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranch)
NS_INTERFACE_MAP_ENTRY(nsIPrefBranchInternal)
NS_INTERFACE_MAP_ENTRY(nsISecurityPref)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END
@@ -583,7 +573,7 @@ NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCou
* nsIPrefBranchInternal methods
*/
NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObserver)
NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak)
{
PrefCallbackData *pCallback;
@@ -602,8 +592,23 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
return NS_ERROR_OUT_OF_MEMORY;
pCallback->pBranch = NS_STATIC_CAST(nsIPrefBranch *, this);
NS_ADDREF(aObserver);
pCallback->pObserver = aObserver;
pCallback->bIsWeakRef = aHoldWeak;
// hold a weak reference to the observer if so requested
nsCOMPtr<nsISupports> observerRef;
if (aHoldWeak) {
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(aObserver);
if (!weakRefFactory) {
// the caller didn't give us a object that supports weak reference... tell them
nsMemory::Free(pCallback);
return NS_ERROR_INVALID_ARG;
}
observerRef = do_GetWeakReference(weakRefFactory);
} else {
observerRef = aObserver;
}
pCallback->pObserver = observerRef;
NS_ADDREF(pCallback->pObserver);
mObservers->AppendElement(pCallback);
mObserverDomains.AppendCString(nsCString(aDomain));
@@ -618,7 +623,7 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
PRInt32 count;
PRInt32 i;
nsresult rv;
nsCString domain;
nsCAutoString domain;
NS_ENSURE_ARG_POINTER(aDomain);
NS_ENSURE_ARG_POINTER(aObserver);
@@ -633,10 +638,21 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
for (i = 0; i < count; i++) {
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
if (pCallback && (pCallback->pObserver == aObserver)) {
mObserverDomains.CStringAt(i, domain);
if (domain.Equals(aDomain))
break;
if (pCallback) {
nsCOMPtr<nsISupports> observerRef;
if (pCallback->bIsWeakRef) {
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(aObserver);
if (weakRefFactory)
observerRef = do_GetWeakReference(aObserver);
}
if (!observerRef)
observerRef = aObserver;
if (pCallback->pObserver == observerRef) {
mObserverDomains.CStringAt(i, domain);
if (domain.Equals(aDomain))
break;
}
}
}
@@ -653,19 +669,72 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
return rv;
}
NS_IMETHODIMP nsPrefBranch::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
{
// watch for xpcom shutdown and free our observers to eliminate any cyclic references
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
freeObserverList();
}
return NS_OK;
}
static int PR_CALLBACK NotifyObserver(const char *newpref, void *data)
{
PrefCallbackData *pData = (PrefCallbackData *)data;
nsCOMPtr<nsIObserver> observer = NS_STATIC_CAST(nsIObserver *, pData->pObserver);
observer->Observe(pData->pBranch,
NS_PREFBRANCH_PREFCHANGE_OBSERVER_ID,
NS_ConvertASCIItoUCS2(newpref).get());
nsCOMPtr<nsIObserver> observer;
if (pData->bIsWeakRef) {
nsIWeakReference *weakRef = NS_STATIC_CAST(nsIWeakReference *, pData->pObserver);
observer = do_QueryReferent(weakRef);
if (!observer) {
// this weak referenced observer went away, remove them from the list
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(pData->pBranch);
if (pbi) {
observer = NS_STATIC_CAST(nsIObserver *, pData->pObserver);
pbi->RemoveObserver(newpref, observer);
}
return 0;
}
} else
observer = NS_STATIC_CAST(nsIObserver *, pData->pObserver);
return 0;
observer->Observe(pData->pBranch, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID,
NS_ConvertASCIItoUCS2(newpref).get());
return 0;
}
void nsPrefBranch::freeObserverList(void)
{
PrefCallbackData *pCallback;
if (mObservers) {
// unregister the observers
PRInt32 count;
count = mObservers->Count();
if (count > 0) {
PRInt32 i;
nsCAutoString domain;
for (i = 0; i < count; i++) {
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
if (pCallback) {
mObserverDomains.CStringAt(i, domain);
PREF_UnregisterCallback(domain, NotifyObserver, pCallback);
NS_RELEASE(pCallback->pObserver);
nsMemory::Free(pCallback);
}
}
// now empty the observer arrays in bulk
mObservers->Clear();
mObserverDomains.Clear();
}
delete mObservers;
mObservers = 0;
}
}
nsresult nsPrefBranch::GetDefaultFromPropertiesFile(const char *aPrefName, PRUnichar **return_buf)
{
nsresult rv;

View File

@@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPrefLocalizedString.h"
@@ -51,6 +52,7 @@
class nsPrefBranch : public nsIPrefBranch,
public nsIPrefBranchInternal,
public nsISecurityPref,
public nsIObserver,
public nsSupportsWeakReference
{
public:
@@ -58,6 +60,7 @@ public:
NS_DECL_NSIPREFBRANCH
NS_DECL_NSIPREFBRANCHINTERNAL
NS_DECL_NSISECURITYPREF
NS_DECL_NSIOBSERVER
nsPrefBranch(const char *aPrefRoot, PRBool aDefaultBranch);
virtual ~nsPrefBranch();
@@ -69,6 +72,7 @@ protected:
nsresult GetDefaultFromPropertiesFile(const char *aPrefName, PRUnichar **return_buf);
const char *getPrefName(const char *aPrefName);
nsresult getValidatedPrefName(const char *aPrefName, const char **_retval);
void freeObserverList(void);
private:
PRInt32 mPrefRootLength;

View File

@@ -259,13 +259,13 @@ NS_IMETHODIMP nsPrefService::GetDefaultBranch(const char *aPrefRoot, nsIPrefBran
// Forward these methods through the nsIPrefBranchInternal headers
NS_IMETHODIMP nsPrefService::AddObserver(const char *aDomain, nsIObserver *aObserver)
NS_IMETHODIMP nsPrefService::AddObserver(const char *aDomain, nsIObserver *aObserver, PRBool aHoldWeak)
{
nsresult rv;
nsCOMPtr<nsIPrefBranchInternal> prefBranch = do_QueryInterface(mRootBranch, &rv);
if (NS_SUCCEEDED(rv))
rv = prefBranch->AddObserver(aDomain, aObserver);
rv = prefBranch->AddObserver(aDomain, aObserver, aHoldWeak);
return rv;
}

View File

@@ -217,16 +217,10 @@ nsIOService::Init()
if (prefBranch) {
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch);
if (pbi)
pbi->AddObserver(PORT_PREF_PREFIX, this);
pbi->AddObserver(PORT_PREF_PREFIX, this, PR_TRUE);
PrefsChanged(prefBranch);
}
// Listen for xpcom-shutdown to break the reference cycle with prefs
nsCOMPtr<nsIObserverService> observerService =
do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv);
if (observerService)
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
return NS_OK;
}
@@ -998,20 +992,10 @@ nsIOService::Observe(nsISupports *subject,
const char *topic,
const PRUnichar *data)
{
if (!nsCRT::strcmp(topic, "nsPref:changed")) {
if (!nsCRT::strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
if (prefBranch)
PrefsChanged(prefBranch, NS_ConvertUCS2toUTF8(data).get());
}
else if (!nsCRT::strcmp(topic,NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
// Clean up the prefs observer to break the reference cycle
nsCOMPtr<nsIPrefBranch> prefBranch;
GetPrefBranch(getter_AddRefs(prefBranch));
if (prefBranch) {
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch);
if (pbi)
pbi->RemoveObserver(PORT_PREF_PREFIX, this);
}
}
return NS_OK;
}

View File

@@ -133,19 +133,19 @@ nsCacheProfilePrefObserver::Install()
nsCOMPtr<nsIPrefBranchInternal> prefInternal = do_QueryInterface(prefService, &rv);
if (NS_FAILED(rv)) return rv;
rv = prefInternal->AddObserver(MEMORY_CACHE_ENABLE_PREF, this);
rv = prefInternal->AddObserver(MEMORY_CACHE_ENABLE_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(DISK_CACHE_ENABLE_PREF, this);
rv = prefInternal->AddObserver(DISK_CACHE_ENABLE_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(DISK_CACHE_DIR_PREF, this);
rv = prefInternal->AddObserver(DISK_CACHE_DIR_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(DISK_CACHE_CAPACITY_PREF, this);
rv = prefInternal->AddObserver(DISK_CACHE_CAPACITY_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = prefInternal->AddObserver(MEMORY_CACHE_CAPACITY_PREF, this);
rv = prefInternal->AddObserver(MEMORY_CACHE_CAPACITY_PREF, this, PR_FALSE);
if (NS_FAILED(rv)) rv2 = rv;
rv = ReadPrefs();
@@ -231,7 +231,7 @@ nsCacheProfilePrefObserver::Observe(nsISupports * subject,
ReadPrefs();
nsCacheService::OnProfileChanged();
} else if (!nsCRT::strcmp("nsPref:changed", topic)) {
} else if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, topic)) {
if (!mHaveProfile) return NS_OK;
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject, &rv);
if (NS_FAILED(rv))

View File

@@ -1076,7 +1076,7 @@ nsDNSService::~nsDNSService()
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsDNSService, nsIDNSService, nsIRunnable);
NS_IMPL_THREADSAFE_ISUPPORTS3(nsDNSService, nsIDNSService, nsIRunnable, nsIObserver);
NS_METHOD
nsDNSService::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
@@ -1139,13 +1139,13 @@ nsDNSService::InstallPrefObserver()
nsCOMPtr<nsIPrefBranchInternal> prefInternal = do_QueryInterface(prefs, &rv);
if (NS_FAILED(rv)) return rv;
rv = prefInternal->AddObserver(NETWORK_DNS_CACHE_ENTRIES, this);
rv = prefInternal->AddObserver(NETWORK_DNS_CACHE_ENTRIES, this, PR_FALSE);
if (NS_FAILED(rv)) return rv;
rv = prefInternal->AddObserver(NETWORK_DNS_CACHE_EXPIRATION, this);
rv = prefInternal->AddObserver(NETWORK_DNS_CACHE_EXPIRATION, this, PR_FALSE);
if (NS_FAILED(rv)) return rv;
rv = prefInternal->AddObserver(NETWORK_ENABLEIDN, this);
rv = prefInternal->AddObserver(NETWORK_ENABLEIDN, this, PR_FALSE);
if (NS_FAILED(rv)) return rv;
// get initial values (if any)
@@ -1198,7 +1198,7 @@ nsDNSService::Observe(nsISupports * subject,
{
nsresult rv = NS_OK;
if (nsCRT::strcmp("nsPref:changed", topic))
if (nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, topic))
return NS_OK;
nsCOMPtr<nsIPrefBranch> prefs = do_QueryInterface(subject, &rv);

View File

@@ -206,11 +206,11 @@ nsHttpHandler::Init()
if (prefBranch) {
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch);
if (pbi) {
pbi->AddObserver(HTTP_PREF_PREFIX, this);
pbi->AddObserver(UA_PREF_PREFIX, this);
pbi->AddObserver(INTL_ACCEPT_LANGUAGES, this);
pbi->AddObserver(INTL_ACCEPT_CHARSET, this);
pbi->AddObserver(NETWORK_ENABLEIDN, this);
pbi->AddObserver(HTTP_PREF_PREFIX, this, PR_TRUE);
pbi->AddObserver(UA_PREF_PREFIX, this, PR_TRUE);
pbi->AddObserver(INTL_ACCEPT_LANGUAGES, this, PR_TRUE);
pbi->AddObserver(INTL_ACCEPT_CHARSET, this, PR_TRUE);
pbi->AddObserver(NETWORK_ENABLEIDN, this, PR_TRUE);
}
PrefsChanged(prefBranch);
}
@@ -252,7 +252,6 @@ nsHttpHandler::Init()
if (observerSvc) {
observerSvc->AddObserver(this, "profile-before-change", PR_TRUE);
observerSvc->AddObserver(this, "session-logout", PR_TRUE);
observerSvc->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
}
return NS_OK;
}
@@ -1811,7 +1810,7 @@ nsHttpHandler::Observe(nsISupports *subject,
const char *topic,
const PRUnichar *data)
{
if (!nsCRT::strcmp(topic, "nsPref:changed")) {
if (!nsCRT::strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(subject);
if (prefBranch)
PrefsChanged(prefBranch, NS_ConvertUCS2toUTF8(data).get());
@@ -1826,20 +1825,6 @@ nsHttpHandler::Observe(nsISupports *subject,
// depend on this value.
mSessionStartTime = NowInSeconds();
}
else if (!nsCRT::strcmp(topic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
nsCOMPtr<nsIPrefBranch> prefBranch;
GetPrefBranch(getter_AddRefs(prefBranch));
if (prefBranch) {
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(prefBranch);
if (pbi) {
pbi->RemoveObserver(HTTP_PREF_PREFIX, this);
pbi->RemoveObserver(UA_PREF_PREFIX, this);
pbi->RemoveObserver(INTL_ACCEPT_LANGUAGES, this);
pbi->RemoveObserver(INTL_ACCEPT_CHARSET, this);
pbi->RemoveObserver(NETWORK_ENABLEIDN, this);
}
}
}
return NS_OK;
}

View File

@@ -47,8 +47,7 @@ var gNavigatorRegionBundle;
var gBrandRegionBundle;
var gLastValidURL = "";
var pref = Components.classes["@mozilla.org/preferences;1"]
.getService(Components.interfaces.nsIPref);
var pref = null;
var appCore = null;
@@ -132,7 +131,7 @@ function UpdateInternetSearchResults(event)
var searchInProgressFlag = search.FindInternetSearchResults(url);
if (searchInProgressFlag) {
var autoOpenSearchPanel = pref.GetBoolPref("browser.search.opensidebarsearchpanel");
var autoOpenSearchPanel = pref.getBoolPref("browser.search.opensidebarsearchpanel");
if (autoOpenSearchPanel)
RevealSearchPanel();
@@ -167,7 +166,8 @@ function getHomePage()
{
var url;
try {
url = pref.getLocalizedUnicharPref("browser.startup.homepage");
url = pref.getComplexValue("browser.startup.homepage",
Components.interfaces.nsIPrefLocalizedString);
} catch (e) {
}
@@ -203,7 +203,9 @@ function UpdateBackForwardButtons()
function nsButtonPrefListener()
{
try {
pref.addObserver(this.domain, this);
var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi)
pbi.addObserver(this.domain, this, false);
} catch(ex) {
dump("Failed to observe prefs: " + ex + "\n");
}
@@ -223,7 +225,7 @@ nsButtonPrefListener.prototype =
var buttonId = buttonName + "-button";
var button = document.getElementById(buttonId);
var show = pref.GetBoolPref(prefName);
var show = pref.getBoolPref(prefName);
if (show)
button.setAttribute("hidden","false");
else
@@ -252,6 +254,13 @@ function Startup()
if (!appCore)
throw Components.results.NS_ERROR_FAILURE;
// Get the preferences service
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
if (!prefService)
throw Components.results.NS_ERROR_FAILURE;
pref = prefService.getBranch(null);
webNavigation = getWebNavigation();
if (!webNavigation)
throw Components.results.NS_ERROR_FAILURE;
@@ -393,8 +402,10 @@ function Shutdown()
}
// unregister us as a pref listener
pref.removeObserver(window.buttonPrefListener.domain,
window.buttonPrefListener);
var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi)
pbi.removeObserver(window.buttonPrefListener.domain,
window.buttonPrefListener);
window.browserContentListener.close();
// Close the app core.
@@ -613,8 +624,9 @@ function OpenSearch(tabName, forceDialogFlag, searchStr)
var forceAsURL = urlmatch.test(searchStr);
try {
autoOpenSearchPanel = pref.GetBoolPref("browser.search.opensidebarsearchpanel");
defaultSearchURL = pref.getLocalizedUnicharPref("browser.search.defaulturl");
autoOpenSearchPanel = pref.getBoolPref("browser.search.opensidebarsearchpanel");
defaultSearchURL = pref.getComplexValue("browser.search.defaulturl",
Components.interfaces.nsIPrefLocalizedString);
} catch (ex) {
}
@@ -638,7 +650,7 @@ function OpenSearch(tabName, forceDialogFlag, searchStr)
} else {
var searchMode = 0;
try {
searchMode = pref.GetIntPref("browser.search.powermode");
searchMode = pref.getIntPref("browser.search.powermode");
} catch(ex) {
}
if (forceDialogFlag || searchMode == 1) {
@@ -666,7 +678,7 @@ function OpenSearch(tabName, forceDialogFlag, searchStr)
searchDS.RememberLastSearchText(escapedSearchStr);
try {
var searchEngineURI = pref.CopyCharPref("browser.search.defaultengine");
var searchEngineURI = pref.getCharPref("browser.search.defaultengine");
if (searchEngineURI) {
var searchURL = searchDS.GetInternetSearchURL(searchEngineURI, escapedSearchStr);
if (searchURL)
@@ -1243,7 +1255,7 @@ function getNewThemes()
function URLBarMouseupHandler(aEvent)
{
if (aEvent.button == 0 && pref.GetBoolPref("browser.urlbar.clickSelectsAll")) {
if (aEvent.button == 0 && pref.getBoolPref("browser.urlbar.clickSelectsAll")) {
var selectionLen = gURLBar.selectionEnd - gURLBar.selectionStart;
if (selectionLen == 0)
gURLBar.setSelectionRange(0, gURLBar.textLength);
@@ -1252,7 +1264,7 @@ function URLBarMouseupHandler(aEvent)
function URLBarBlurHandler(aEvent)
{
if (pref.GetBoolPref("browser.urlbar.clickSelectsAll"))
if (pref.getBoolPref("browser.urlbar.clickSelectsAll"))
gURLBar.setSelectionRange(0, 0);
}

View File

@@ -50,8 +50,7 @@ var gLastValidURL = "";
var gHaveUpdatedToolbarState = false;
var gClickSelectsAll = -1;
var pref = Components.classes["@mozilla.org/preferences;1"]
.getService(Components.interfaces.nsIPref);
var pref = null;
var appCore = null;
@@ -133,7 +132,7 @@ function UpdateInternetSearchResults(event)
var searchInProgressFlag = search.FindInternetSearchResults(url);
if (searchInProgressFlag) {
var autoOpenSearchPanel = pref.GetBoolPref("browser.search.opensidebarsearchpanel");
var autoOpenSearchPanel = pref.getBoolPref("browser.search.opensidebarsearchpanel");
if (autoOpenSearchPanel)
RevealSearchPanel();
@@ -168,7 +167,8 @@ function getHomePage()
{
var url;
try {
url = pref.getLocalizedUnicharPref("browser.startup.homepage");
url = pref.getComplexValue("browser.startup.homepage",
Components.interfaces.nsIPrefLocalizedString);
} catch (e) {
}
@@ -204,7 +204,9 @@ function UpdateBackForwardButtons()
function nsButtonPrefListener()
{
try {
pref.addObserver(this.domain, this);
var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi)
pbi.addObserver(this.domain, this, false);
} catch(ex) {
dump("Failed to observe prefs: " + ex + "\n");
}
@@ -224,7 +226,7 @@ nsButtonPrefListener.prototype =
var buttonId = buttonName + "-button";
var button = document.getElementById(buttonId);
var show = pref.GetBoolPref(prefName);
var show = pref.getBoolPref(prefName);
if (show)
button.setAttribute("hidden","false");
else
@@ -275,6 +277,13 @@ function Startup()
if (!appCore)
throw "couldn't create a browser instance";
// Get the preferences service
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
if (!prefService)
throw "couldn't create a preferences service";
pref = prefService.getBranch(null);
webNavigation = getWebNavigation();
if (!webNavigation)
throw "no XBL binding for browser";
@@ -447,8 +456,10 @@ function Shutdown()
BrowserFlushBookmarksAndHistory();
// unregister us as a pref listener
pref.removeObserver(window.buttonPrefListener.domain,
window.buttonPrefListener);
var pbi = pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi)
pbi.removeObserver(window.buttonPrefListener.domain,
window.buttonPrefListener);
window.browserContentListener.close();
// Close the app core.
@@ -458,8 +469,8 @@ function Shutdown()
function Translate()
{
var service = pref.CopyCharPref("browser.translation.service");
var serviceDomain = pref.CopyCharPref("browser.translation.serviceDomain");
var service = pref.getCharPref("browser.translation.service");
var serviceDomain = pref.getCharPref("browser.translation.serviceDomain");
// XXX This somehow causes a big leak, back to the old way
// till we figure out why. See bug 61886.
@@ -685,8 +696,9 @@ function OpenSearch(tabName, forceDialogFlag, searchStr)
var forceAsURL = urlmatch.test(searchStr);
try {
autoOpenSearchPanel = pref.GetBoolPref("browser.search.opensidebarsearchpanel");
defaultSearchURL = pref.getLocalizedUnicharPref("browser.search.defaulturl");
autoOpenSearchPanel = pref.getBoolPref("browser.search.opensidebarsearchpanel");
defaultSearchURL = pref.getComplexValue("browser.search.defaulturl",
Components.interfaces.nsIPrefLocalizedString);
} catch (ex) {
}
@@ -709,7 +721,7 @@ function OpenSearch(tabName, forceDialogFlag, searchStr)
} else {
var searchMode = 0;
try {
searchMode = pref.GetIntPref("browser.search.powermode");
searchMode = pref.getIntPref("browser.search.powermode");
} catch(ex) {
}
if (forceDialogFlag || searchMode == 1) {
@@ -736,7 +748,7 @@ function OpenSearch(tabName, forceDialogFlag, searchStr)
searchDS.RememberLastSearchText(escapedSearchStr);
try {
var searchEngineURI = pref.CopyCharPref("browser.search.defaultengine");
var searchEngineURI = pref.getCharPref("browser.search.defaultengine");
if (searchEngineURI) {
var searchURL = getSearchUrl("actionButton");
if (searchURL) {
@@ -944,7 +956,7 @@ function BrowserLoadURL()
if (url.match(/^view-source:/)) {
BrowserViewSourceOfURL(url.replace(/^view-source:/, ""), null);
} else {
if (pref && pref.GetBoolPref("browser.tabs.opentabfor.urlbar") && getBrowser().localName == "tabbrowser") {
if (pref && pref.getBoolPref("browser.tabs.opentabfor.urlbar") && getBrowser().localName == "tabbrowser") {
var t = getBrowser().addTab(getShortcutOrURI(url)); // open link in new tab
getBrowser().selectedTab = t;
}
@@ -1362,7 +1374,9 @@ function applyTheme(themeName)
chromeRegistry.uninstallSkin( themeName.getAttribute("name"), true );
// XXX - this sucks and should only be temporary.
pref.SetUnicharPref("general.skins.removelist." + themeName.getAttribute("name"), true);
pref.setComplexValue("general.skins.removelist." + themeName.getAttribute("name"),
Components.interfaces.nsISupportsWString,
true);
if (inUse)
chromeRegistry.refreshSkins();
@@ -1374,7 +1388,9 @@ function applyTheme(themeName)
// XXX XXX BAD BAD BAD BAD !! XXX XXX
// we STILL haven't fixed editor skin switch problems
// hacking around it yet again
pref.SetUnicharPref("general.skins.selectedSkin", themeName.getAttribute("name"));
pref.setComplexValue("general.skins.selectedSkin",
Components.interfaces.nsISupportsWString,
themeName.getAttribute("name"));
var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.notifyObservers(null, "skin-selected", null);
@@ -1398,7 +1414,7 @@ function URLBarFocusHandler(aEvent)
{
if (gURLBar) {
if (gClickSelectsAll == -1)
gClickSelectsAll = pref.GetBoolPref("browser.urlbar.clickSelectsAll");
gClickSelectsAll = pref.getBoolPref("browser.urlbar.clickSelectsAll");
if (gClickSelectsAll)
gURLBar.setSelectionRange(0, gURLBar.textLength);
}

View File

@@ -8,19 +8,25 @@
<binding id="urlbar" extends="chrome://global/content/autocomplete.xml#autocomplete">
<implementation>
<constructor><![CDATA[
this.mPrefs.addObserver("browser.urlbar", this.mPrefObserver);
var pbi = this.mPrefs.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi)
pbi.addObserver("browser.urlbar", this.mPrefObserver, false);
this.updatePref("browser.urlbar.showPopup");
this.updatePref("browser.urlbar.autoFill");
]]></constructor>
<destructor><![CDATA[
this.mPrefs.removeObserver("browser.urlbar", this.mPrefObserver);
var pbi = this.mPrefs.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi)
pbi.removeObserver("browser.urlbar", this.mPrefObserver);
]]></destructor>
<property name="mPrefs">
Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
</property>
<field name="mPrefs">
var svc = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
svc.getBranch(null);
</field>
<property name="mPrefObserver"><![CDATA[
({
@@ -37,9 +43,9 @@
<parameter name="aPref"/>
<body><![CDATA[
if (!aPref.indexOf("browser.urlbar.showPopup")) {
this.showPopup = this.mPrefs.GetBoolPref("browser.urlbar.showPopup");
this.showPopup = this.mPrefs.getBoolPref("browser.urlbar.showPopup");
} else if (!aPref.indexOf("browser.urlbar.autoFill")) {
this.autoFill = this.mPrefs.GetBoolPref("browser.urlbar.autoFill");
this.autoFill = this.mPrefs.getBoolPref("browser.urlbar.autoFill");
}
]]></body>
</method>
@@ -60,13 +66,19 @@
<implementation>
<constructor><![CDATA[
// listen for changes to default search engine
this.mPrefs.addObserver("browser.search", this.mPrefObserver);
this.mPrefs.addObserver("browser.urlbar", this.mPrefObserver);
var pbi = this.mPrefs.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi) {
pbi.addObserver("browser.search", this.mPrefObserver, false);
pbi.addObserver("browser.urlbar", this.mPrefObserver, false);
}
]]></constructor>
<destructor><![CDATA[
this.mPrefs.removeObserver("browser.search", this.mPrefObserver);
this.mPrefs.removeObserver("browser.urlbar", this.mPrefObserver);
var pbi = this.mPrefs.QueryInterface(Components.interfaces.nsIPrefBranchInternal);
if (pbi) {
pbi.removeObserver("browser.search", this.mPrefObserver);
pbi.removeObserver("browser.urlbar", this.mPrefObserver);
}
]]></destructor>
<property name="selectedIndex"
@@ -108,9 +120,11 @@
document.getAnonymousElementByAttribute(this, "role", "search-box");
</property>
<property name="mPrefs">
Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
</property>
<field name="mPrefs">
var svc = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
svc.getBranch(null);
</field>
<property name="mPrefObserver"><![CDATA[
({
@@ -155,7 +169,7 @@
<parameter name="aPref"/>
<body><![CDATA[
if (!aPref.indexOf("browser.urlbar.showSearch"))
this.showSearch = this.mPrefs.GetBoolPref("browser.urlbar.showSearch");
this.showSearch = this.mPrefs.getBoolPref("browser.urlbar.showSearch");
]]></body>
</method>
@@ -196,10 +210,12 @@
var defaultEngine = null;
try {
defaultEngine = this.mPrefs.CopyUnicharPref("browser.search.defaultengine");
defaultEngine = this.mPrefs.getComplexValue("browser.search.defaultengine",
Components.interfaces.nsISupportsWString);
} catch(ex) {
this.ensureDefaultEnginePrefs(rdf, ds);
defaultEngine = this.mPrefs.CopyUnicharPref("browser.search.defaultengine");
defaultEngine = this.mPrefs.getComplexValue("browser.search.defaultengine",
Components.interfaces.nsISupportsWString);
}
if (defaultEngine) {
@@ -227,7 +243,8 @@
<parameter name="aRDF"/>
<parameter name="aDS"/>
<body><![CDATA[
var defaultName = this.mPrefs.getLocalizedUnicharPref("browser.search.defaultenginename");
var defaultName = this.mPrefs.getComplexValue("browser.search.defaultenginename",
Components.interfaces.nsIPrefLocalizedString);
const kNC_Root = aRDF.GetResource("NC:SearchEngineRoot");
const kNC_child = aRDF.GetResource("http://home.netscape.com/NC-rdf#child");
const kNC_Name = aRDF.GetResource("http://home.netscape.com/NC-rdf#Name");
@@ -237,7 +254,9 @@
var engineRes = arcs.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var name = this.readRDFString(aDS, engineRes, kNC_Name);
if (name == defaultName)
this.mPrefs.SetUnicharPref("browser.search.defaultengine", engineRes.Value);
this.mPrefs.setComplexValue("browser.search.defaultengine",
Components.interfaces.nsISupportsWString,
engineRes.Value);
}
]]></body>
</method>

View File

@@ -52,7 +52,10 @@
#include "nsCollationCID.h"
#include "nsLocaleCID.h"
#include "nsILocaleService.h"
#include "nsIPref.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPrefLocalizedString.h"
#include "nsICurrentCharsetListener.h"
#include "nsQuickSort.h"
#include "nsIObserver.h"
@@ -179,7 +182,7 @@ private:
nsCOMPtr<nsIRDFService> mRDFService;
nsCOMPtr<nsICharsetConverterManager2> mCCManager;
nsCOMPtr<nsIPref> mPrefService;
nsCOMPtr<nsIPrefBranch> mPrefs;
nsCOMPtr<nsIObserver> mCharsetMenuObserver;
nsCOMPtr<nsISupportsArray> mDecoderList;
nsCOMPtr<nsISupportsArray> mEncoderList;
@@ -343,7 +346,7 @@ NS_IMETHODIMP nsCharsetMenuObserver::Observe(nsISupports *aSubject, const char *
{
nsresult rv;
if (!nsCRT::strcmp(aTopic, "nsPref:changed")) {
if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
nsDependentString prefName(someData);
if (prefName.Equals(NS_LITERAL_STRING(kBrowserStaticPrefKey))) {
@@ -681,7 +684,11 @@ nsresult nsCharsetMenu::InitResources()
res = mCCManager->GetEncoderList(getter_AddRefs(mEncoderList));
if (NS_FAILED(res)) return res;
mPrefService = do_GetService(NS_PREF_CONTRACTID, &res);
nsCOMPtr<nsIPrefService> mPrefService;
mPrefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &res);
if (NS_FAILED(res)) return res;
res = mPrefService->GetBranch(nsnull, getter_AddRefs(mPrefs));
if (NS_FAILED(res)) return res;
mCharsetMenuObserver = new nsCharsetMenuObserver(this);
@@ -698,13 +705,16 @@ nsresult nsCharsetMenu::FreeResources()
nsresult res = NS_OK;
if (mCharsetMenuObserver) {
mPrefService->RemoveObserver(kBrowserStaticPrefKey, mCharsetMenuObserver);
mPrefService->RemoveObserver(kMaileditPrefKey, mCharsetMenuObserver);
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(mPrefs);
if (pbi) {
pbi->RemoveObserver(kBrowserStaticPrefKey, mCharsetMenuObserver);
pbi->RemoveObserver(kMaileditPrefKey, mCharsetMenuObserver);
}
}
mRDFService = NULL;
mCCManager = NULL;
mPrefService = NULL;
mRDFService = NULL;
mCCManager = NULL;
mPrefs = NULL;
return res;
}
@@ -730,7 +740,7 @@ nsresult nsCharsetMenu::InitBrowserMenu()
// mark the end of the static area, the rest is cache
mBrowserCacheStart = mBrowserMenu.Count();
mPrefService->GetIntPref(kBrowserCacheSizePrefKey, &mBrowserCacheSize);
mPrefs->GetIntPref(kBrowserCacheSizePrefKey, &mBrowserCacheSize);
// compute the position of the menu in the RDF container
res = container->GetCount(&mBrowserMenuRDFPosition);
@@ -744,7 +754,9 @@ nsresult nsCharsetMenu::InitBrowserMenu()
NS_ASSERTION(NS_SUCCEEDED(res), "error initializing browser cache charset menu");
// register prefs callback
res = mPrefService->AddObserver(kBrowserStaticPrefKey, mCharsetMenuObserver);
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(mPrefs);
if (pbi)
res = pbi->AddObserver(kBrowserStaticPrefKey, mCharsetMenuObserver, PR_FALSE);
return res;
}
@@ -765,7 +777,9 @@ nsresult nsCharsetMenu::InitMaileditMenu()
NS_ASSERTION(NS_SUCCEEDED(res), "error initializing mailedit charset menu from prefs");
// register prefs callback
res = mPrefService->AddObserver(kMaileditPrefKey, mCharsetMenuObserver);
nsCOMPtr<nsIPrefBranchInternal> pbi = do_QueryInterface(mPrefs);
if (pbi)
res = pbi->AddObserver(kMaileditPrefKey, mCharsetMenuObserver, PR_FALSE);
return res;
}
@@ -789,7 +803,7 @@ nsresult nsCharsetMenu::InitMailviewMenu()
// mark the end of the static area, the rest is cache
mMailviewCacheStart = mMailviewMenu.Count();
mPrefService->GetIntPref(kMailviewCacheSizePrefKey, &mMailviewCacheSize);
mPrefs->GetIntPref(kMailviewCacheSizePrefKey, &mMailviewCacheSize);
// compute the position of the menu in the RDF container
res = container->GetCount(&mMailviewMenuRDFPosition);
@@ -824,7 +838,7 @@ nsresult nsCharsetMenu::InitComposerMenu()
// mark the end of the static area, the rest is cache
mComposerCacheStart = mComposerMenu.Count();
mPrefService->GetIntPref(kComposerCacheSizePrefKey, &mComposerCacheSize);
mPrefs->GetIntPref(kComposerCacheSizePrefKey, &mComposerCacheSize);
// compute the position of the menu in the RDF container
res = container->GetCount(&mComposerMenuRDFPosition);
@@ -1215,14 +1229,16 @@ nsresult nsCharsetMenu::AddFromPrefsToMenu(
{
nsresult res = NS_OK;
PRUnichar * value = NULL;
res = mPrefService->GetLocalizedUnicharPref(aKey, &value);
nsCOMPtr<nsIPrefLocalizedString> pls;
res = mPrefs->GetComplexValue(aKey, NS_GET_IID(nsIPrefLocalizedString), getter_AddRefs(pls));
if (NS_FAILED(res)) return res;
if (value != NULL) {
res = AddFromStringToMenu(NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(value).get()), aArray, aContainer,
aDecs, aIDPrefix);
nsMemory::Free(value);
if (pls != NULL) {
nsXPIDLString ucsval;
pls->ToString(getter_Copies(ucsval));
if (ucsval)
res = AddFromStringToMenu(NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(ucsval).get()), aArray,
aContainer, aDecs, aIDPrefix);
}
return res;
@@ -1238,7 +1254,7 @@ nsresult nsCharsetMenu::AddFromNolocPrefsToMenu(
nsresult res = NS_OK;
char * value = NULL;
res = mPrefService->CopyCharPref(aKey, &value);
res = mPrefs->GetCharPref(aKey, &value);
if (NS_FAILED(res)) return res;
if (value != NULL) {
@@ -1365,7 +1381,7 @@ nsresult nsCharsetMenu::WriteCacheToPrefs(nsVoidArray * aArray,
}
// write the pref
res = mPrefService->SetCharPref(aKey, NS_ConvertUCS2toUTF8(cache).get());
res = mPrefs->SetCharPref(aKey, NS_ConvertUCS2toUTF8(cache).get());
return res;
}