mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1205586 - new Date().toLocale{,Date,Time}String() should return appropriately differing strings as the local time zone/default locale change. r=till
This commit is contained in:
parent
2cf79d22b7
commit
5e91264490
@ -5,9 +5,73 @@
|
||||
/*global intl_DateTimeFormat: false, */
|
||||
|
||||
|
||||
// This cache, once primed, has these properties:
|
||||
//
|
||||
// runtimeDefaultLocale:
|
||||
// Locale information provided by the embedding, guiding SpiderMonkey's
|
||||
// selection of a default locale. See RuntimeDefaultLocale(), whose
|
||||
// value controls the value returned by DefaultLocale() that's what's
|
||||
// *actually* used.
|
||||
// localTZA:
|
||||
// The local time zone's adjustment from UTC. See LocalTZA().
|
||||
// formatters:
|
||||
// A Record storing formatters consistent with the above
|
||||
// runtimeDefaultLocale/localTZA values, for use with the appropriate
|
||||
// ES6 toLocale*String Date method when called with its first two
|
||||
// arguments having the value |undefined|.
|
||||
//
|
||||
// The "formatters" Record has (some subset of) these properties, as determined
|
||||
// by all values of the first argument passed to |GetCachedFormat|:
|
||||
//
|
||||
// dateTimeFormat: for Date's toLocaleString operation
|
||||
// dateFormat: for Date's toLocaleDateString operation
|
||||
// timeFormat: for Date's toLocaleTimeString operation
|
||||
//
|
||||
// Using this cache, then, requires 1) verifying the current
|
||||
// runtimeDefaultLocale/localTZA are consistent with cached values, then
|
||||
// 2) seeing if the desired formatter is cached and returning it if so, or else
|
||||
// 3) create the desired formatter and store and return it.
|
||||
var dateTimeFormatCache = new Record();
|
||||
|
||||
|
||||
/**
|
||||
* Get a cached DateTimeFormat formatter object, created like so:
|
||||
*
|
||||
* var opts = ToDateTimeOptions(undefined, required, defaults);
|
||||
* return new Intl.DateTimeFormat(undefined, opts);
|
||||
*
|
||||
* |format| must be a key from the "formatters" Record described above.
|
||||
*/
|
||||
function GetCachedFormat(format, required, defaults) {
|
||||
assert(format === "dateTimeFormat" ||
|
||||
format === "dateFormat" ||
|
||||
format === "timeFormat",
|
||||
"unexpected format key: please update the comment by " +
|
||||
"dateTimeFormatCache");
|
||||
|
||||
var runtimeDefaultLocale = RuntimeDefaultLocale();
|
||||
var localTZA = LocalTZA();
|
||||
|
||||
var formatters;
|
||||
if (dateTimeFormatCache.runtimeDefaultLocale !== runtimeDefaultLocale ||
|
||||
dateTimeFormatCache.localTZA !== localTZA)
|
||||
{
|
||||
formatters = dateTimeFormatCache.formatters = new Record();
|
||||
dateTimeFormatCache.runtimeDefaultLocale = runtimeDefaultLocale;
|
||||
dateTimeFormatCache.localTZA = localTZA;
|
||||
} else {
|
||||
formatters = dateTimeFormatCache.formatters;
|
||||
}
|
||||
|
||||
var fmt = formatters[format];
|
||||
if (fmt === undefined) {
|
||||
var options = ToDateTimeOptions(undefined, required, defaults);
|
||||
fmt = formatters[format] = intl_DateTimeFormat(undefined, options);
|
||||
}
|
||||
|
||||
return fmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format this Date object into a date and time string, using the locale and
|
||||
* formatting options provided.
|
||||
@ -30,11 +94,7 @@ function Date_toLocaleString() {
|
||||
if (locales === undefined && options === undefined) {
|
||||
// This cache only optimizes for the old ES5 toLocaleString without
|
||||
// locales and options.
|
||||
if (dateTimeFormatCache.dateTimeFormat === undefined) {
|
||||
options = ToDateTimeOptions(options, "any", "all");
|
||||
dateTimeFormatCache.dateTimeFormat = intl_DateTimeFormat(locales, options);
|
||||
}
|
||||
dateTimeFormat = dateTimeFormatCache.dateTimeFormat;
|
||||
dateTimeFormat = GetCachedFormat("dateTimeFormat", "any", "all");
|
||||
} else {
|
||||
options = ToDateTimeOptions(options, "any", "all");
|
||||
dateTimeFormat = intl_DateTimeFormat(locales, options);
|
||||
@ -67,11 +127,7 @@ function Date_toLocaleDateString() {
|
||||
if (locales === undefined && options === undefined) {
|
||||
// This cache only optimizes for the old ES5 toLocaleDateString without
|
||||
// locales and options.
|
||||
if (dateTimeFormatCache.dateFormat === undefined) {
|
||||
options = ToDateTimeOptions(options, "date", "date");
|
||||
dateTimeFormatCache.dateFormat = intl_DateTimeFormat(locales, options);
|
||||
}
|
||||
dateTimeFormat = dateTimeFormatCache.dateFormat;
|
||||
dateTimeFormat = GetCachedFormat("dateFormat", "date", "date");
|
||||
} else {
|
||||
options = ToDateTimeOptions(options, "date", "date");
|
||||
dateTimeFormat = intl_DateTimeFormat(locales, options);
|
||||
@ -104,11 +160,7 @@ function Date_toLocaleTimeString() {
|
||||
if (locales === undefined && options === undefined) {
|
||||
// This cache only optimizes for the old ES5 toLocaleTimeString without
|
||||
// locales and options.
|
||||
if (dateTimeFormatCache.timeFormat === undefined) {
|
||||
options = ToDateTimeOptions(options, "time", "time");
|
||||
dateTimeFormatCache.timeFormat = intl_DateTimeFormat(locales, options);
|
||||
}
|
||||
dateTimeFormat = dateTimeFormatCache.timeFormat;
|
||||
dateTimeFormat = GetCachedFormat("timeFormat", "time", "time");
|
||||
} else {
|
||||
options = ToDateTimeOptions(options, "time", "time");
|
||||
dateTimeFormat = intl_DateTimeFormat(locales, options);
|
||||
|
@ -18,6 +18,7 @@ UNIFIED_SOURCES += [
|
||||
'testClassGetter.cpp',
|
||||
'testCloneScript.cpp',
|
||||
'testContexts.cpp',
|
||||
'testDateToLocaleString.cpp',
|
||||
'testDebugger.cpp',
|
||||
'testDeepFreeze.cpp',
|
||||
'testDefineGetterSetterNonEnumerable.cpp',
|
||||
|
54
js/src/jsapi-tests/testDateToLocaleString.cpp
Normal file
54
js/src/jsapi-tests/testDateToLocaleString.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
BEGIN_TEST(testDateToLocaleString)
|
||||
{
|
||||
// This test should only attempt to run if we have Intl support: necessary
|
||||
// to properly assume that changes to the default locale will predictably
|
||||
// affect the behavior of the locale-sensitive Date methods tested here.
|
||||
JS::Rooted<JS::Value> haveIntl(cx);
|
||||
EVAL("typeof Intl !== 'undefined'", &haveIntl);
|
||||
if (!haveIntl.toBoolean())
|
||||
return true;
|
||||
|
||||
// Pervasive assumption: our Intl support includes "de" (German) and
|
||||
// "en" (English) and treats them differently for purposes of
|
||||
// Date.prototype.toLocale{,Date,Time}String behavior.
|
||||
|
||||
// Start with German.
|
||||
CHECK(JS_SetDefaultLocale(rt, "de"));
|
||||
|
||||
// The (constrained) Date object we'll use to test behavior.
|
||||
EXEC("var d = new Date(Date.UTC(2015, 9 - 1, 17));");
|
||||
|
||||
// Test that toLocaleString behavior changes with default locale changes.
|
||||
EXEC("var deAll = d.toLocaleString();");
|
||||
|
||||
CHECK(JS_SetDefaultLocale(rt, "en"));
|
||||
EXEC("if (d.toLocaleString() === deAll) \n"
|
||||
" throw 'toLocaleString results should have changed with system locale change';");
|
||||
|
||||
// Test that toLocaleDateString behavior changes with default locale changes.
|
||||
EXEC("var enDate = d.toLocaleDateString();");
|
||||
|
||||
CHECK(JS_SetDefaultLocale(rt, "de"));
|
||||
EXEC("if (d.toLocaleDateString() === enDate) \n"
|
||||
" throw 'toLocaleDateString results should have changed with system locale change';");
|
||||
|
||||
// Test that toLocaleTimeString behavior changes with default locale changes.
|
||||
EXEC("var deTime = d.toLocaleTimeString();");
|
||||
|
||||
CHECK(JS_SetDefaultLocale(rt, "en"));
|
||||
EXEC("if (d.toLocaleTimeString() === deTime) \n"
|
||||
" throw 'toLocaleTimeString results should have changed with system locale change';");
|
||||
|
||||
JS_ResetDefaultLocale(rt);
|
||||
return true;
|
||||
}
|
||||
END_TEST(testDateToLocaleString)
|
@ -1204,6 +1204,16 @@ intrinsic_RuntimeDefaultLocale(JSContext* cx, unsigned argc, Value* vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_LocalTZA(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
MOZ_ASSERT(args.length() == 0, "the LocalTZA intrinsic takes no arguments");
|
||||
|
||||
args.rval().setDouble(cx->runtime()->dateTimeInfo.localTZA());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
intrinsic_IsConstructing(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
@ -1324,6 +1334,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
||||
JS_FN("_ConstructorForTypedArray", intrinsic_ConstructorForTypedArray, 1,0),
|
||||
JS_FN("DecompileArg", intrinsic_DecompileArg, 2,0),
|
||||
JS_FN("RuntimeDefaultLocale", intrinsic_RuntimeDefaultLocale, 0,0),
|
||||
JS_FN("LocalTZA", intrinsic_LocalTZA, 0,0),
|
||||
|
||||
JS_INLINABLE_FN("_IsConstructing", intrinsic_IsConstructing, 0,0,
|
||||
IntrinsicIsConstructing),
|
||||
|
Loading…
Reference in New Issue
Block a user