Fix #64, Non-English month parsing doesn't work in Standalone

Month values from the Firefox language packs are included in a
JSON file used by `Zotero.Date.getMonths()`. `getMonths(true)` includes
English months as well.

The JSON file should be bundled with the connectors as well, and
Zotero.Date.init() should be updated to populate the month data from
that.
This commit is contained in:
Dan Stillman 2017-01-09 04:21:45 -05:00
parent 7bdcc17ed0
commit ef1ff8bc42
4 changed files with 1477 additions and 31 deletions

View file

@ -39,39 +39,75 @@ Zotero.Date = new function(){
this.getLocaleDateOrder = getLocaleDateOrder;
var _localeDateOrder = null;
var _months = null;
var _months;
var _monthsWithEnglish;
/**
* Load dateFormat bundle into _dateFormatsBundle
*/
this.getMonths = function() {
if(_months) return _months;
if(Zotero.isFx && !Zotero.isBookmarklet) {
var src = 'chrome://global/locale/dateFormat.properties';
var localeService = Components.classes['@mozilla.org/intl/nslocaleservice;1'].
getService(Components.interfaces.nsILocaleService);
var appLocale = localeService.getApplicationLocale();
var bundle =
Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService).createBundle(src, appLocale);
_months = {"short":[], "long":[]};
for(var i=1; i<=12; i++) {
_months.short.push(bundle.GetStringFromName("month."+i+".Mmm"));
_months.long.push(bundle.GetStringFromName("month."+i+".name"));
}
} else {
// TODO localize for Chrome/Safari
_months = {
"short":["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"],
"long":["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"]};
this.init = Zotero.Promise.coroutine(function* () {
if (!Zotero.isFx || Zotero.isBookmarklet) {
throw new Error("Unimplemented");
}
return _months;
var json = (yield Zotero.HTTP.request(
'GET', 'resource://zotero/schema/dateFormats.json', { responseType: 'json' }
)).response;
var locale = Zotero.locale;
var english = locale.startsWith('en');
// If no exact match, try first two characters ('de')
if (!json[locale]) {
locale = locale.substr(0, 2);
}
// Try first two characters repeated ('de-DE')
if (!json[locale]) {
locale = locale + "-" + locale.toUpperCase();
}
// Look for another locale with same first two characters
if (!json[locale]) {
let sameLang = Object.keys(json).filter(l => l.startsWith(locale.substr(0, 2)));
if (sameLang.length) {
locale = sameLang[0];
}
}
// If all else fails, use English
if (!json[locale]) {
locale = 'en-US';
english = true;
}
_months = json[locale];
// Add English versions if not already added
if (english) {
_monthsWithEnglish = _months;
}
else {
_monthsWithEnglish = {};
for (let key in _months) {
_monthsWithEnglish[key] = _months[key].concat(json['en-US'][key]);
}
}
});
/**
* @param {Boolean} [withEnglish = false] - Include English months
* @return {Object} - Object with 'short' and 'long' arrays
*/
this.getMonths = function (withEnglish) {
if (withEnglish) {
if (_monthsWithEnglish) return _monthsWithEnglish;
}
else {
if (_months) return _months;
}
if (Zotero.isFx && !Zotero.isBookmarklet) {
throw new Error("Months not cached");
}
// TODO: Use JSON file for connectors
return _months = _monthsWithEnglish = {
short: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
long: ["January", "February", "March", "April", "May", "June", "July", "August",
"September", "October", "November", "December"]};
}
/**

View file

@ -717,7 +717,7 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
// Initialize keyboard shortcuts
Zotero.Keys.init();
// Initialize Locate Manager
yield Zotero.Date.init();
Zotero.LocateManager.init();
yield Zotero.ID.init();
yield Zotero.Collections.init();

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,122 @@
describe("Zotero.Date", function() {
describe("#getMonths()", function () {
var origLocale;
var englishShort = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
var englishLong = [
"January", "February", "March", "April", "May", "June", "July", "August", "September",
"October", "November", "December"
];
var frenchShort = [
"jan", "fév", "mar", "avr", "mai", "jun", "jul", "aoû", "sep", "oct", "nov", "dec"
];
var frenchLong = [
"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre",
"octobre", "novembre", "décembre"
];
before(function () {
origLocale = Zotero.locale;
});
after(function () {
Zotero.locale = origLocale;
});
describe("English", function () {
beforeEach(function* () {
if (Zotero.locale != 'en-US') {
Zotero.locale = 'en-US';
yield Zotero.Date.init();
}
});
it("should get English short months", function () {
let months = Zotero.Date.getMonths().short;
assert.lengthOf(months, 12);
assert.sameMembers(months, englishShort);
});
it("should get English long months", function () {
let months = Zotero.Date.getMonths().long;
assert.lengthOf(months, 12);
assert.sameMembers(months, englishLong);
});
it("shouldn't repeat months in 'withEnglish' mode", function () {
let months = Zotero.Date.getMonths(true).short;
assert.lengthOf(months, 12);
assert.sameMembers(months, englishShort);
});
it("should resolve to English from unknown locale", function* () {
Zotero.locale = 'zz';
yield Zotero.Date.init();
let months = Zotero.Date.getMonths().short;
assert.lengthOf(months, 12);
assert.sameMembers(months, englishShort);
});
it("shouldn't repeat English with unknown locale", function* () {
Zotero.locale = 'zz';
yield Zotero.Date.init();
let months = Zotero.Date.getMonths(true).short;
assert.lengthOf(months, 12);
assert.sameMembers(months, englishShort);
});
});
describe("French", function () {
beforeEach(function* () {
if (Zotero.locale != 'fr-FR') {
Zotero.locale = 'fr-FR';
yield Zotero.Date.init();
}
});
it("should get French short months", function () {
let months = Zotero.Date.getMonths().short;
assert.lengthOf(months, 12);
assert.sameMembers(months, frenchShort);
});
it("should get French long months", function () {
let months = Zotero.Date.getMonths().long;
assert.lengthOf(months, 12);
assert.sameMembers(months, frenchLong);
});
it("should get French short months with English", function () {
let months = Zotero.Date.getMonths(true).short;
assert.lengthOf(months, 24);
assert.sameMembers(months, frenchShort.concat(englishShort));
});
it("should get French long months with English", function () {
let months = Zotero.Date.getMonths(true).long;
assert.lengthOf(months, 24);
assert.sameMembers(months, frenchLong.concat(englishLong));
});
it("should resolve from two-letter locale", function* () {
Zotero.locale = 'fr';
yield Zotero.Date.init();
let months = Zotero.Date.getMonths().short;
assert.lengthOf(months, 12);
assert.sameMembers(months, frenchShort);
});
it("should resolve from unknown four-letter locale with common prefix", function* () {
Zotero.locale = 'fr-ZZ';
yield Zotero.Date.init();
let months = Zotero.Date.getMonths().short;
assert.lengthOf(months, 12);
assert.sameMembers(months, frenchShort);
});
});
});
describe("#sqlToDate()", function () {
it("should convert an SQL local date into a JS Date object", function* () {
var d1 = new Date();