File mozilla-ua-locale.patch of Package seamonkey

From: upstream
Subject: allow reading general.useragent.locale from user profile
References:
https://bugzilla.mozilla.org/show_bug.cgi?id=519468
https://bugzilla.mozilla.org/show_bug.cgi?id=542999
http://bugzilla.novell.com/show_bug.cgi?id=582654

diff --git a/chrome/src/nsChromeRegistry.cpp b/chrome/src/nsChromeRegistry.cpp
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -545,58 +545,39 @@ nsChromeRegistry::Init()
   if (safeMode)
     prefserv->GetDefaultBranch(nsnull, getter_AddRefs(prefs));
   else
     prefs = do_QueryInterface(prefserv);
 
   if (!prefs) {
     NS_WARNING("Could not get pref service!");
   }
-
-  PRBool useLocalePref = PR_TRUE;
-
-  if (prefs) {
-    // check the pref first
-    PRBool matchOS = PR_FALSE;
-    rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOS);
-
-    // match os locale
-    if (NS_SUCCEEDED(rv) && matchOS) {
-      // compute lang and region code only when needed!
-      nsCAutoString uiLocale;
-      rv = getUILangCountry(uiLocale);
-      if (NS_SUCCEEDED(rv)) {
-        useLocalePref = PR_FALSE;
-        mSelectedLocale = uiLocale;
-      }
-    }
-  }
-      
-  if (prefs) {
+  else {
     nsXPIDLCString provider;
-
     rv = prefs->GetCharPref(SELECTED_SKIN_PREF, getter_Copies(provider));
     if (NS_SUCCEEDED(rv))
       mSelectedSkin = provider;
 
+    SelectLocalePref(prefs);
+
     nsCOMPtr<nsIPrefBranch2> prefs2 (do_QueryInterface(prefs));
 
-    if (prefs2)
+    if (prefs2) {
+      rv = prefs2->AddObserver(MATCH_OS_LOCALE_PREF, this, PR_TRUE);
+      rv = prefs2->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
       rv = prefs2->AddObserver(SELECTED_SKIN_PREF, this, PR_TRUE);
-
-    if (useLocalePref) {
-      rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
-      if (NS_SUCCEEDED(rv))
-        mSelectedLocale = provider;
-      
-      if (prefs2)
-        prefs2->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
     }
   }
 
+  nsCOMPtr<nsIObserverService> obsService (do_GetService("@mozilla.org/observer-service;1"));
+  if (obsService) {
+    obsService->AddObserver(this, "command-line-startup", PR_TRUE);
+    obsService->AddObserver(this, "profile-initial-state", PR_TRUE);
+  }
+
   CheckForNewChrome();
 
   mInitialized = PR_TRUE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -1479,40 +1460,68 @@ nsChromeRegistry::ProcessNewChromeBuffer
     
     while (aBuffer < bufferEnd && (*aBuffer == '\0' || *aBuffer == ' ' || *aBuffer == '\r' || *aBuffer == '\n'))
       ++aBuffer;
   }
 
   return NS_OK;
 }
 
+nsresult
+nsChromeRegistry::SelectLocalePref(nsIPrefBranch* prefs)
+{
+  nsresult rv;
+  PRBool matchOSLocale = PR_FALSE, userLocaleOverride = PR_FALSE;
+  prefs->PrefHasUserValue(SELECTED_LOCALE_PREF, &userLocaleOverride);
+  rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOSLocale);
+
+  if (NS_SUCCEEDED(rv) && matchOSLocale && !userLocaleOverride) {
+    // compute lang and region code only when needed!
+    nsCAutoString uiLocale;
+    rv = getUILangCountry(uiLocale);
+    if (NS_SUCCEEDED(rv))
+      mSelectedLocale = uiLocale;
+  }
+  else {
+    nsXPIDLCString provider;
+    rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
+    if (NS_SUCCEEDED(rv)) {
+      mSelectedLocale = provider;
+    }
+  }
+
+  return rv;
+}
+
 NS_IMETHODIMP nsChromeRegistry::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
 {
   nsresult rv = NS_OK;
 
   if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
     nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
     NS_ASSERTION(prefs, "Bad observer call!");
 
     NS_ConvertUTF16toUTF8 pref(someData);
 
-    nsXPIDLCString provider;
-    rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
-    if (NS_FAILED(rv)) {
-      NS_ERROR("Couldn't get new locale or skin pref!");
-      return rv;
+    if (pref.EqualsLiteral(MATCH_OS_LOCALE_PREF) ||
+        pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
+      rv = SelectLocalePref(prefs);
+      if (NS_SUCCEEDED(rv) && mProfileLoaded)
+        FlushAllCaches();
     }
-
-    if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
+    else if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
+      nsXPIDLCString provider;
+      rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
+      if (NS_FAILED(rv)) {
+        NS_ERROR("Couldn't get new locale pref!");
+        return rv;
+      }
+
       mSelectedSkin = provider;
       RefreshSkins();
-    }
-    else if (pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
-      mSelectedLocale = provider;
-      FlushAllCaches();
     } else {
       NS_ERROR("Unexpected pref!");
     }
   }
   else if (!strcmp("command-line-startup", aTopic)) {
     nsCOMPtr<nsICommandLine> cmdLine (do_QueryInterface(aSubject));
     if (cmdLine) {
       nsAutoString uiLocale;
@@ -1522,16 +1531,19 @@ NS_IMETHODIMP nsChromeRegistry::Observe(
         CopyUTF16toUTF8(uiLocale, mSelectedLocale);
         nsCOMPtr<nsIPrefBranch2> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
         if (prefs) {
           prefs->RemoveObserver(SELECTED_LOCALE_PREF, this);
         }
       }
     }
   }
+  else if (!strcmp("profile-initial-state", aTopic)) {
+    mProfileLoaded = PR_TRUE;
+  }
   else {
     NS_ERROR("Unexpected observer topic!");
   }
 
   return rv;
 }
 
 #ifdef MOZ_XUL
diff --git a/chrome/src/nsChromeRegistry.h b/chrome/src/nsChromeRegistry.h
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -56,16 +56,17 @@
 #include "nsInterfaceHashtable.h"
 
 struct PRFileDesc;
 class nsIAtom;
 class nsICSSLoader;
 class nsICSSStyleSheet;
 class nsIDOMWindowInternal;
 class nsILocalFile;
+class nsIPrefBranch;
 class nsIRDFDataSource;
 class nsIRDFResource;
 class nsIRDFService;
 class nsISimpleEnumerator;
 class nsIURL;
 
 // for component registration
 // {47049e42-1d87-482a-984d-56ae185e367a}
@@ -89,17 +90,17 @@ public:
 
 #ifdef MOZ_XUL
   NS_DECL_NSIXULOVERLAYPROVIDER
 #endif
 
   NS_DECL_NSIOBSERVER
 
   // nsChromeRegistry methods:
-  nsChromeRegistry() : mInitialized(PR_FALSE) {
+  nsChromeRegistry() : mInitialized(PR_FALSE), mProfileLoaded(PR_FALSE) {
     mPackagesHash.ops = nsnull;
   }
   ~nsChromeRegistry();
 
   nsresult Init();
 
   static nsChromeRegistry* gChromeRegistry;
 
@@ -110,16 +111,18 @@ protected:
 
   nsresult LoadInstallDataSource();
   nsresult LoadProfileDataSource();
 
   void FlushSkinCaches();
   void FlushAllCaches();
 
 private:
+  nsresult SelectLocalePref(nsIPrefBranch* prefs);
+
   static nsresult RefreshWindow(nsIDOMWindowInternal* aWindow,
                                 nsICSSLoader* aCSSLoader);
   static nsresult GetProviderAndPath(nsIURL* aChromeURL,
                                      nsACString& aProvider, nsACString& aPath);
 
 #ifdef MOZ_XUL
   NS_HIDDEN_(void) ProcessProvider(PRFileDesc *fd, nsIRDFService* aRDFs,
                                    nsIRDFDataSource* ds, nsIRDFResource* aRoot,
@@ -239,16 +242,17 @@ public:
     const nsCOMArray<nsIURI>* GetArray(nsIURI* aBase);
 
   private:
     nsTHashtable<OverlayListEntry> mTable;
   };
 
 private:
   PRBool mInitialized;
+  PRBool mProfileLoaded;
 
   // Hash of package names ("global") to PackageEntry objects
   PLDHashTable mPackagesHash;
 
   // Hashes on the file to be overlaid (chrome://browser/content/browser.xul)
   // to a list of overlays/stylesheets
   OverlayListHash mOverlayHash;
   OverlayListHash mStyleHash;
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -811,16 +811,18 @@ nsXREDirProvider::DoStartup()
     static const PRUnichar kStartup[] = {'s','t','a','r','t','u','p','\0'};
     obsSvc->NotifyObservers(nsnull, "profile-do-change", kStartup);
     obsSvc->NotifyObservers(nsnull, "profile-after-change", kStartup);
 
     // Any component that has registered for the profile-after-change category
     // should also be created at this time.
     (void)NS_CreateServicesFromCategory("profile-after-change", nsnull,
                                         "profile-after-change");
+
+    obsSvc->NotifyObservers(nsnull, "profile-initial-state", nsnull);
   }
   return NS_OK;
 }
 
 class ProfileChangeStatusImpl : public nsIProfileChangeStatus
 {
 public:
   NS_DECL_ISUPPORTS
openSUSE Build Service is sponsored by