mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 153586 - Date.toLocaleString() not returning locale string.
r=jst, sr=brendan
This commit is contained in:
parent
8f8f2a8f03
commit
9f26f1dadb
@ -78,6 +78,9 @@
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
// For locale aware string methods
|
||||
#include "plstr.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsILocaleService.h"
|
||||
#include "nsICollation.h"
|
||||
@ -139,6 +142,7 @@ static nsIScriptSecurityManager *sSecurityManager;
|
||||
|
||||
static nsICollation *gCollation;
|
||||
|
||||
static nsIUnicodeDecoder *gDecoder;
|
||||
|
||||
void JS_DLL_CALLBACK
|
||||
NS_ScriptErrorReporter(JSContext *cx,
|
||||
@ -300,6 +304,80 @@ NS_ScriptErrorReporter(JSContext *cx,
|
||||
::JS_ClearPendingException(cx);
|
||||
}
|
||||
|
||||
JS_STATIC_DLL_CALLBACK(JSBool)
|
||||
LocaleToUnicode(JSContext *cx, char *src, jsval *rval)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!gDecoder) {
|
||||
// use app default locale
|
||||
nsCOMPtr<nsILocaleService> localeService =
|
||||
do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsILocale> appLocale;
|
||||
rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString localeStr;
|
||||
rv = appLocale->
|
||||
GetCategory(NS_LITERAL_STRING(NSILOCALE_TIME), localeStr);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get app locale info");
|
||||
|
||||
nsCOMPtr<nsIPlatformCharset> platformCharset =
|
||||
do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString charset;
|
||||
rv = platformCharset->GetDefaultCharsetForLocale(localeStr, charset);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// get/create unicode decoder for charset
|
||||
nsCOMPtr<nsICharsetConverterManager> ccm =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
ccm->GetUnicodeDecoder(charset.get(), &gDecoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSString *str = nsnull;
|
||||
PRInt32 srcLength = PL_strlen(src);
|
||||
|
||||
if (gDecoder) {
|
||||
PRInt32 unicharLength = srcLength;
|
||||
PRUnichar *unichars = (PRUnichar *)malloc((srcLength + 1) * sizeof(PRUnichar));
|
||||
if (unichars) {
|
||||
rv = gDecoder->Convert(src, &srcLength, unichars, &unicharLength);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// terminate the returned string
|
||||
unichars[unicharLength] = 0;
|
||||
|
||||
// nsIUnicodeDecoder::Convert may use fewer than srcLength PRUnichars
|
||||
if (unicharLength + 1 < srcLength + 1) {
|
||||
PRUnichar *shrunkUnichars =
|
||||
(PRUnichar *)realloc(unichars, (unicharLength + 1) * sizeof(PRUnichar));
|
||||
if (shrunkUnichars)
|
||||
unichars = shrunkUnichars;
|
||||
}
|
||||
str = JS_NewUCString(cx,
|
||||
NS_REINTERPRET_CAST(jschar*, unichars),
|
||||
unicharLength);
|
||||
}
|
||||
if (!str)
|
||||
free(unichars);
|
||||
}
|
||||
}
|
||||
|
||||
if (!str) {
|
||||
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_OUT_OF_MEMORY);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static JSBool
|
||||
ChangeCase(JSContext *cx, JSString *src, jsval *rval,
|
||||
void(* changeCaseFnc)(const nsAString&, nsAString&))
|
||||
@ -577,7 +655,8 @@ nsJSContext::nsJSContext(JSRuntime *aRuntime) : mGCOnDestruction(PR_TRUE)
|
||||
{
|
||||
LocaleToUpperCase,
|
||||
LocaleToLowerCase,
|
||||
LocaleCompare
|
||||
LocaleCompare,
|
||||
LocaleToUnicode
|
||||
};
|
||||
|
||||
::JS_SetLocaleCallbacks(mContext, &localeCallbacks);
|
||||
@ -634,6 +713,7 @@ nsJSContext::~nsJSContext()
|
||||
NS_IF_RELEASE(sRuntimeService);
|
||||
NS_IF_RELEASE(sSecurityManager);
|
||||
NS_IF_RELEASE(gCollation);
|
||||
NS_IF_RELEASE(gDecoder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2045,6 +2125,7 @@ void nsJSEnvironment::ShutDown()
|
||||
NS_IF_RELEASE(sRuntimeService);
|
||||
NS_IF_RELEASE(sSecurityManager);
|
||||
NS_IF_RELEASE(gCollation);
|
||||
NS_IF_RELEASE(gDecoder);
|
||||
}
|
||||
|
||||
sDidShutdown = PR_TRUE;
|
||||
|
@ -192,9 +192,9 @@ nsLocaleService::nsLocaleService(void)
|
||||
#if (defined(XP_UNIX) && !defined(XP_MACOSX)) || defined(XP_BEOS)
|
||||
nsCOMPtr<nsIPosixLocale> posixConverter = do_CreateInstance(NS_POSIXLOCALE_CONTRACTID);
|
||||
|
||||
nsAutoString xpLocale, platformLocale;
|
||||
nsAutoString xpLocale;
|
||||
if (posixConverter) {
|
||||
nsAutoString category, category_platform;
|
||||
nsAutoString category;
|
||||
nsLocale* resultLocale;
|
||||
int i;
|
||||
|
||||
@ -206,27 +206,19 @@ nsLocaleService::nsLocaleService(void)
|
||||
nsresult result;
|
||||
char* lc_temp = setlocale(posix_locale_category[i], "");
|
||||
category.AssignWithConversion(LocaleList[i]);
|
||||
category_platform.AssignWithConversion(LocaleList[i]);
|
||||
category_platform.Append(NS_LITERAL_STRING("##PLATFORM"));
|
||||
if (lc_temp != nsnull) {
|
||||
result = posixConverter->GetXPLocale(lc_temp, xpLocale);
|
||||
platformLocale.AssignWithConversion(lc_temp);
|
||||
} else {
|
||||
char* lang = getenv("LANG");
|
||||
if ( lang == nsnull ) {
|
||||
platformLocale.Assign(NS_LITERAL_STRING("en_US"));
|
||||
if ( lang == nsnull )
|
||||
result = posixConverter->GetXPLocale("en-US", xpLocale);
|
||||
}
|
||||
else {
|
||||
else
|
||||
result = posixConverter->GetXPLocale(lang, xpLocale);
|
||||
platformLocale.AssignWithConversion(lang);
|
||||
}
|
||||
}
|
||||
if (NS_FAILED(result)) {
|
||||
return;
|
||||
}
|
||||
resultLocale->AddCategory(category, xpLocale);
|
||||
resultLocale->AddCategory(category_platform, platformLocale);
|
||||
}
|
||||
mSystemLocale = do_QueryInterface(resultLocale);
|
||||
mApplicationLocale = do_QueryInterface(resultLocale);
|
||||
|
@ -115,7 +115,7 @@ nsresult nsCollationUnix::Initialize(nsILocale* locale)
|
||||
mLocale.Assign('C');
|
||||
|
||||
nsAutoString localeStr;
|
||||
NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_COLLATE##PLATFORM");
|
||||
NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_COLLATE");
|
||||
|
||||
// get locale string, use app default if no locale specified
|
||||
if (locale == nsnull) {
|
||||
|
@ -55,7 +55,7 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsDateTimeFormatUnix, nsIDateTimeFormat)
|
||||
nsresult nsDateTimeFormatUnix::Initialize(nsILocale* locale)
|
||||
{
|
||||
nsAutoString localeStr;
|
||||
NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_TIME##PLATFORM");
|
||||
NS_NAMED_LITERAL_STRING(aCategory, "NSILOCALE_TIME");
|
||||
nsresult res = NS_OK;
|
||||
|
||||
// use cached info if match with stored locale
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "nsAutoLock.h"
|
||||
#include "prinit.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIPosixLocale.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsPlatformCharset, nsIPlatformCharset)
|
||||
|
||||
@ -325,7 +326,7 @@ NS_IMETHODIMP
|
||||
nsPlatformCharset::Init()
|
||||
{
|
||||
nsCAutoString charset;
|
||||
nsresult res;
|
||||
nsresult res = NS_OK;
|
||||
|
||||
//
|
||||
// remember default locale so we can use the
|
||||
@ -334,9 +335,14 @@ nsPlatformCharset::Init()
|
||||
char* locale = setlocale(LC_CTYPE, nsnull);
|
||||
NS_ASSERTION(locale, "cannot setlocale");
|
||||
if (locale) {
|
||||
mLocale.AssignWithConversion(locale);
|
||||
nsCOMPtr<nsIPosixLocale> posixConverter =
|
||||
do_CreateInstance(NS_POSIXLOCALE_CONTRACTID);
|
||||
if (posixConverter)
|
||||
res = posixConverter->GetXPLocale(locale, mLocale);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
} else {
|
||||
mLocale.Assign(NS_LITERAL_STRING("en_US"));
|
||||
mLocale.Assign(NS_LITERAL_STRING("en-US"));
|
||||
}
|
||||
|
||||
res = InitGetCharset(charset);
|
||||
|
@ -1562,6 +1562,7 @@ struct JSLocaleCallbacks {
|
||||
JSLocaleToUpperCase localeToUpperCase;
|
||||
JSLocaleToLowerCase localeToLowerCase;
|
||||
JSLocaleCompare localeCompare;
|
||||
JSLocaleToUnicode localeToUnicode;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -52,6 +52,7 @@
|
||||
|
||||
#include "jsstddef.h"
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -1645,6 +1646,9 @@ date_toLocaleHelper(JSContext *cx, JSObject *obj, uintN argc,
|
||||
|
||||
}
|
||||
|
||||
if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode)
|
||||
return cx->localeCallbacks->localeToUnicode(cx, buf, rval);
|
||||
|
||||
str = JS_NewStringCopyZ(cx, buf);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
@ -547,6 +547,9 @@ typedef JSBool
|
||||
JSString *src1, JSString *src2,
|
||||
jsval *rval);
|
||||
|
||||
typedef JSBool
|
||||
(* JS_DLL_CALLBACK JSLocaleToUnicode)(JSContext *cx, char *src, jsval *rval);
|
||||
|
||||
/*
|
||||
* Security protocol types.
|
||||
*/
|
||||
|
@ -112,6 +112,8 @@
|
||||
|
||||
#include "SpecialSystemDirectory.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
// Registry Factory creation function defined in nsRegistry.cpp
|
||||
// We hook into this function locally to create and register the registry
|
||||
// Since noone outside xpcom needs to know about this and nsRegistry.cpp
|
||||
@ -440,6 +442,11 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result,
|
||||
rv = nsMemoryImpl::Startup();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// If the locale hasn't already been setup by our embedder,
|
||||
// get us out of the "C" locale and into the system
|
||||
if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_OS2)
|
||||
NS_StartupNativeCharsetUtils();
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user