Bug 1481790 - Determine locale dependent default values for preferences without a localized preference file. r=philipp
--- a/calendar/base/content/calendar-chrome-startup.js
+++ b/calendar/base/content/calendar-chrome-startup.js
@@ -8,16 +8,19 @@ ChromeUtils.import("resource://gre/modul
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
/* exported commonInitCalendar, commonFinishCalendar */
/**
* Common initialization steps for calendar chrome windows.
*/
function commonInitCalendar() {
+ // load locale specific default values for preferences
+ setLocaleDefaultPreferences();
+
// Move around toolbarbuttons and whatever is needed in the UI.
migrateCalendarUI();
// Load the Calendar Manager
loadCalendarManager();
// set up the unifinder
prepareCalendarToDoUnifinder();
@@ -218,8 +221,56 @@ function migrateCalendarUI() {
}
}
Preferences.set("calendar.ui.version", UI_VERSION);
} catch (e) {
cal.ERROR("Error upgrading UI from " + currentUIVersion + " to " +
UI_VERSION + ": " + e);
}
}
+
+function setLocaleDefaultPreferences() {
+ function setDefaultLocaleValue(aName) {
+ let startDefault = calendarInfo.firstDayOfWeek - 1;
+ if (aName == "calendar.categories.names" &&
+ defaultBranch.getStringPref(aName) == "") {
+ defaultBranch.setStringPref(aName, cal.l10n.getString("categories", "categories2"));
+ } else if (aName == "calendar.week.start" &&
+ defaultBranch.getIntPref(aName) != startDefault) {
+ defaultBranch.setIntPref(aName, startDefault);
+ } else if (aName.startsWith("calendar.week.d")) {
+ let weStart = calendarInfo.weekendStart - 1;
+ let weEnd = calendarInfo.weekendEnd - 1;
+ if (weStart > weEnd) {
+ weEnd += 7;
+ }
+ let weekend = [];
+ for (let i = weStart; i <= weEnd; i++) {
+ weekend.push(i > 6 ? i - 7 : i);
+ }
+ if (defaultBranch.getBoolPref(aName) === weekend.includes(aName[15])) {
+ defaultBranch.setBoolPref(aName, weekend.includes(aName[15]));
+ }
+ }
+ }
+
+ cal.LOG("Start loading of locale dependent preference default values...");
+
+ let defaultBranch = Services.prefs.getDefaultBranch("");
+ let calendarInfo = cal.l10n.calendarInfo();
+
+ let prefDefaults = [
+ "calendar.week.start",
+ "calendar.week.d0sundaysoff",
+ "calendar.week.d1mondaysoff",
+ "calendar.week.d2tuesdaysoff",
+ "calendar.week.d3wednesdaysoff",
+ "calendar.week.d4thursdaysoff",
+ "calendar.week.d5fridaysoff",
+ "calendar.week.d6saturdaysoff",
+ "calendar.categories.names"
+ ];
+ for (let prefDefault of prefDefaults) {
+ setDefaultLocaleValue(prefDefault);
+ }
+
+ cal.LOG("Loading of locale sensitive preference default values completed.");
+}
--- a/calendar/base/modules/utils/calL10NUtils.jsm
+++ b/calendar/base/modules/utils/calL10NUtils.jsm
@@ -39,16 +39,45 @@ function _getString(aComponent, aBundleN
} catch (ex) {
let msg = `Failed to read '${aStringName}' from ${propName}.`;
Components.utils.reportError(`${msg} Error: ${ex}`);
return aStringName;
}
}
_getString._bundleCache = {};
+/**
+ * Provides locale dependent parameters for displaying calendar views
+ *
+ * @param {String} aLocale The locale to get the info for, e.g. "en-US",
+ * "de-DE" or null for the current locale
+ * @param {Bollean} aResetCache Whether to reset the internal cache - for test
+ * purposes only don't use it otherwise atm
+ * @return {Object} The getCalendarInfo object from mozIMozIntl
+ */
+function _calendarInfo(aLocale=null, aResetCache=false) {
+ if (aResetCache) {
+ _calendarInfo._startup = {};
+ }
+ // we cache the result to prevent updates at runtime except for test
+ // purposes since changing intl.regional_prefs.use_os_locales preference
+ // would provide different result when called without aLocale and we
+ // need to investigate whether this is wanted or chaching more selctively.
+ // when starting to use it to deteremine the first week of a year, we would
+ // need to at least reset that chached properties on pref change.
+ if (!("firstDayOfWeek" in _calendarInfo._startup) || aLocale) {
+ let info = Services.intl.getCalendarInfo(aLocale);
+ if (aLocale) {
+ return info;
+ }
+ _calendarInfo._startup = info;
+ }
+ return _calendarInfo._startup;
+}
+_calendarInfo._startup = {};
var call10n = {
/**
* Gets the value of a string in a .properties file.
*
* @param {String} aComponent Stringbundle component name
* @param {String} aBundleName The name of the properties file
* @param {String} aStringName The name of the string within the properties file
@@ -129,10 +158,19 @@ var call10n = {
*
* @param {String[]} aStringArray The strings to sort
* @return {String[]} The sorted strings, more specifically aStringArray
*/
sortArrayByLocaleCollator: function(aStringArray) {
let collator = call10n.createLocaleCollator();
aStringArray.sort((a, b) => collator.compareString(0, a, b));
return aStringArray;
- }
+ },
+
+ /**
+ * Provides locale dependent parameters for displaying calendar views
+ *
+ * @param {String} aLocale The locale to get the info for, e.g. "en-US",
+ * "de-DE" or null for the current locale
+ * @return {Object} The getCalendarInfo object from mozIMozIntl
+ */
+ calendarInfo: _calendarInfo
};
new file mode 100644
--- /dev/null
+++ b/calendar/test/unit/test_l10n_utils.js
@@ -0,0 +1,107 @@
+/* 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/. */
+
+ChromeUtils.import("resource://gre/modules/Preferences.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+function run_test() {
+ do_calendar_startup(run_next_test);
+}
+
+// tests for calL10NUtils.jsm
+/* Incomplete - still missing test coverage for:
+ * getAnyString
+ * getString
+ * getCalString
+ * getLtnString
+ * getDateFmtString
+ * formatMonth
+ * createLocaleCollator
+*/
+
+add_task(async function calendarInfo_test() {
+ let data = [{
+ input: { locale: "en-US" },
+ expected: {
+ properties: [
+ "firstDayOfWeek", "minDays", "weekendStart", "weekendEnd",
+ "calendar", "locale"
+ ]
+ }
+ }, {
+ input: { locale: "EN-US" },
+ expected: {
+ properties: [
+ "firstDayOfWeek", "minDays", "weekendStart", "weekendEnd",
+ "calendar", "locale"
+ ]
+ }
+ }, {
+ input: { locale: "et" },
+ expected: {
+ properties: [
+ "firstDayOfWeek", "minDays", "weekendStart", "weekendEnd",
+ "calendar", "locale"
+ ]
+ }
+ }, {
+ input: { locale: null }, // this also would trigger caching tests
+ expected: {
+ properties: [
+ "firstDayOfWeek", "minDays", "weekendStart", "weekendEnd",
+ "calendar", "locale"
+ ]
+ }
+ }];
+ let useOSLocaleFormat = Preferences.get("intl.regional_prefs.use_os_locales", false);
+ // let localeService = Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService);
+ let osprefs = Cc["@mozilla.org/intl/ospreferences;1"].getService(Ci.mozIOSPreferences);
+ let appLocale = Services.locale.getAppLocalesAsBCP47()[0];
+ let rsLocale = osprefs.getRegionalPrefsLocales()[0];
+
+ let i = 0;
+ for (let test of data) {
+ i++;
+ let info = cal.l10n.calendarInfo(test.input.locale);
+ equal(
+ Object.keys(info).length,
+ test.expected.properties.length,
+ "expected number of attributes (test #" + i + ")"
+ );
+ for (let prop of test.expected.properties) {
+ ok(prop in info, prop + " exists (test #" + i + ")");
+ }
+
+ if (!test.input.locale && appLocale != rsLocale) {
+ // if aLoacle is null we test with the current date and time formatting setting
+ // let's test the caching mechanism - this test section is pointless if app and
+ // OS locale are the same like probably on automation
+ Preferences.set("intl.regional_prefs.use_os_locales", !useOSLocaleFormat);
+ let info2 = cal.l10n.calendarInfo();
+ equal(
+ Object.keys(info).length,
+ test.expected.properties.length,
+ "caching test - equal number of properties (test #" + i + ")"
+ );
+ for (let prop of Object.keys(info)) {
+ ok(prop in info2,
+ "caching test - " + prop + " exists in both objects (test #" + i + ")");
+ equal(
+ info2[prop],
+ info[prop],
+ "caching test - value for " + prop + " is equal in both objects (test #" + i + ")"
+ );
+ }
+ // we reset the cache and test again - it's suffient here to find one changed property,
+ // so we use locale since that must change always in that scenario
+ info2 = cal.l10n.calendarInfo(null, true);
+ Preferences.set("intl.regional_prefs.use_os_locales", useOSLocaleFormat);
+ notEqual(
+ info2.locale,
+ info.locale,
+ "caching retest - value for locale is different in both objects (test #" + i + ")"
+ );
+ }
+ }
+});
--- a/calendar/test/unit/xpcshell-shared.ini
+++ b/calendar/test/unit/xpcshell-shared.ini
@@ -32,16 +32,17 @@
[test_gdata_provider.js]
skip-if = true # See bug 1481180. requesttimeoutfactor = 2
[test_hashedarray.js]
[test_ics.js]
[test_ics_parser.js]
[test_ics_service.js]
[test_imip.js]
[test_items.js]
+[test_l10n_utils.js]
[test_ltninvitationutils.js]
[test_providers.js]
[test_recur.js]
[test_relation.js]
[test_rfc3339_parser.js]
[test_search_service.js]
[test_startup_service.js]
[test_storage.js]