Add Zotero.intl namespace
Move `Zotero.getString()` and intl init code to `Zotero.intl` to make it easier to re-use. Link `Zotero.getString()` to `Zotero.intl.getString()`. Do not expose `getStringFromBundle`, `pluralFormGet`, and `pluralFormNumForms` because they are not used.
This commit is contained in:
parent
e8cd4c9338
commit
38166d4e05
3 changed files with 137 additions and 92 deletions
133
chrome/content/zotero/xpcom/intl.js
Normal file
133
chrome/content/zotero/xpcom/intl.js
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright © 2018 Center for History and New Media
|
||||||
|
George Mason University, Fairfax, Virginia, USA
|
||||||
|
http://zotero.org
|
||||||
|
|
||||||
|
This file is part of Zotero.
|
||||||
|
|
||||||
|
Zotero is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Zotero is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
*/
|
||||||
|
Zotero.intl = new function () {
|
||||||
|
let bundle;
|
||||||
|
let intlProps;
|
||||||
|
let pluralFormGet;
|
||||||
|
let pluralFormNumForms;
|
||||||
|
|
||||||
|
// Get settings from language pack (extracted by zotero-build/locale/merge_mozilla_files)
|
||||||
|
this.init = function () {
|
||||||
|
bundle = Services.strings.createBundle('chrome://zotero/locale/zotero.properties');
|
||||||
|
intlProps = Services.strings.createBundle('chrome://zotero/locale/mozilla/intl.properties');
|
||||||
|
|
||||||
|
[pluralFormGet, pluralFormNumForms] = PluralForm.makeGetter(parseInt(getIntlProp('pluralRule', 1)));
|
||||||
|
setOrClearIntlPref('intl.accept_languages', 'string');
|
||||||
|
|
||||||
|
Zotero.locale = getIntlProp('general.useragent.locale', 'en-US');
|
||||||
|
|
||||||
|
// Also load the brand as appName
|
||||||
|
Zotero.appName = Services.strings
|
||||||
|
.createBundle('chrome://branding/locale/brand.properties')
|
||||||
|
.GetStringFromName('brandShortName');
|
||||||
|
|
||||||
|
// Set the locale direction to Zotero.dir
|
||||||
|
Zotero.dir = 'ltr';
|
||||||
|
|
||||||
|
// TODO: is there a better way to get the entity from JS?
|
||||||
|
if (!(Zotero.isNode || Zotero.isElectron)) {
|
||||||
|
let xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||||
|
.createInstance();
|
||||||
|
xmlhttp.open('GET', 'chrome://global/locale/global.dtd', false);
|
||||||
|
xmlhttp.overrideMimeType('text/plain');
|
||||||
|
xmlhttp.send(null);
|
||||||
|
let matches = xmlhttp.responseText.match(/(ltr|rtl)/);
|
||||||
|
if (matches && matches[0] == 'rtl') {
|
||||||
|
Zotero.dir = 'rtl';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.rtl = (Zotero.dir === 'rtl');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function getIntlProp(name, fallback = null) {
|
||||||
|
try {
|
||||||
|
return intlProps.GetStringFromName(name);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
Zotero.logError(`Couldn't load ${name} from intl.properties`);
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setOrClearIntlPref(name, type) {
|
||||||
|
var val = getIntlProp(name);
|
||||||
|
if (val !== null) {
|
||||||
|
if (type == 'boolean') {
|
||||||
|
val = val == 'true';
|
||||||
|
}
|
||||||
|
Zotero.Prefs.set(name, val, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Zotero.Prefs.clear(name, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} name
|
||||||
|
* @param {String[]} [params=[]] - Strings to substitute for placeholders
|
||||||
|
* @param {Number} [num] - Number (also appearing in `params`) to use when determining which plural
|
||||||
|
* form of the string to use; localized strings should include all forms in the order specified
|
||||||
|
* in https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals,
|
||||||
|
* separated by semicolons
|
||||||
|
*/
|
||||||
|
this.getString = function (name, params, num) {
|
||||||
|
try {
|
||||||
|
var l10n;
|
||||||
|
if (params != undefined) {
|
||||||
|
if (typeof params != 'object'){
|
||||||
|
params = [params];
|
||||||
|
}
|
||||||
|
l10n = bundle.formatStringFromName(name, params, params.length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l10n = bundle.GetStringFromName(name);
|
||||||
|
}
|
||||||
|
if (num !== undefined) {
|
||||||
|
let availableForms = l10n.split(/;/);
|
||||||
|
// If not enough available forms, use last one -- PluralForm.get() uses first by
|
||||||
|
// default, but it's more likely that a localizer will translate the two English
|
||||||
|
// strings with some plural form as the second one, so we might as well use that
|
||||||
|
if (availableForms.length < pluralFormNumForms()) {
|
||||||
|
l10n = availableForms[availableForms.length - 1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l10n = pluralFormGet(num, l10n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
if (e.name == 'NS_ERROR_ILLEGAL_VALUE') {
|
||||||
|
Zotero.debug(params, 1);
|
||||||
|
}
|
||||||
|
else if (e.name != 'NS_ERROR_FAILURE') {
|
||||||
|
Zotero.logError(e);
|
||||||
|
}
|
||||||
|
throw new Error('Localized string not available for ' + name);
|
||||||
|
}
|
||||||
|
return l10n;
|
||||||
|
};
|
||||||
|
};
|
|
@ -225,59 +225,8 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
|
||||||
// Browser
|
// Browser
|
||||||
Zotero.browser = "g";
|
Zotero.browser = "g";
|
||||||
|
|
||||||
//
|
Zotero.intl.init();
|
||||||
// Get settings from language pack (extracted by zotero-build/locale/merge_mozilla_files)
|
|
||||||
//
|
|
||||||
function getIntlProp(name, fallback = null) {
|
|
||||||
try {
|
|
||||||
return intlProps.GetStringFromName(name);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
Zotero.logError(`Couldn't load ${name} from intl.properties`);
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function setOrClearIntlPref(name, type) {
|
|
||||||
var val = getIntlProp(name);
|
|
||||||
if (val !== null) {
|
|
||||||
if (type == 'boolean') {
|
|
||||||
val = val == 'true';
|
|
||||||
}
|
|
||||||
Zotero.Prefs.set(name, val, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Zotero.Prefs.clear(name, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var intlProps = Services.strings.createBundle("chrome://zotero/locale/mozilla/intl.properties");
|
|
||||||
this.locale = getIntlProp('general.useragent.locale', 'en-US');
|
|
||||||
let [get, numForms] = PluralForm.makeGetter(parseInt(getIntlProp('pluralRule', 1)));
|
|
||||||
this.pluralFormGet = get;
|
|
||||||
this.pluralFormNumForms = numForms;
|
|
||||||
setOrClearIntlPref('intl.accept_languages', 'string');
|
|
||||||
|
|
||||||
// Also load the brand as appName
|
|
||||||
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
|
||||||
this.appName = brandBundle.GetStringFromName("brandShortName");
|
|
||||||
|
|
||||||
_localizedStringBundle = Services.strings.createBundle("chrome://zotero/locale/zotero.properties");
|
|
||||||
|
|
||||||
// Set the locale direction to Zotero.dir
|
|
||||||
// DEBUG: is there a better way to get the entity from JS?
|
|
||||||
var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
|
||||||
.createInstance();
|
|
||||||
xmlhttp.open('GET', 'chrome://global/locale/global.dtd', false);
|
|
||||||
xmlhttp.overrideMimeType('text/plain');
|
|
||||||
xmlhttp.send(null);
|
|
||||||
var matches = xmlhttp.responseText.match(/(ltr|rtl)/);
|
|
||||||
if (matches && matches[0] == 'rtl') {
|
|
||||||
Zotero.dir = 'rtl';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Zotero.dir = 'ltr';
|
|
||||||
}
|
|
||||||
Zotero.rtl = Zotero.dir == 'rtl';
|
|
||||||
|
|
||||||
Zotero.Prefs.init();
|
Zotero.Prefs.init();
|
||||||
Zotero.Debug.init(options && options.forceDebugLog);
|
Zotero.Debug.init(options && options.forceDebugLog);
|
||||||
|
|
||||||
|
@ -1412,47 +1361,9 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
|
||||||
* separated by semicolons
|
* separated by semicolons
|
||||||
*/
|
*/
|
||||||
this.getString = function (name, params, num) {
|
this.getString = function (name, params, num) {
|
||||||
return this.getStringFromBundle(_localizedStringBundle, ...arguments);
|
return Zotero.intl.getString(...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.getStringFromBundle = function (bundle, name, params, num) {
|
|
||||||
try {
|
|
||||||
if (params != undefined) {
|
|
||||||
if (typeof params != 'object'){
|
|
||||||
params = [params];
|
|
||||||
}
|
|
||||||
var l10n = bundle.formatStringFromName(name, params, params.length);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var l10n = bundle.GetStringFromName(name);
|
|
||||||
}
|
|
||||||
if (num !== undefined) {
|
|
||||||
let availableForms = l10n.split(/;/);
|
|
||||||
// If not enough available forms, use last one -- PluralForm.get() uses first by
|
|
||||||
// default, but it's more likely that a localizer will translate the two English
|
|
||||||
// strings with some plural form as the second one, so we might as well use that
|
|
||||||
if (availableForms.length < this.pluralFormNumForms()) {
|
|
||||||
l10n = availableForms[availableForms.length - 1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
l10n = this.pluralFormGet(num, l10n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e){
|
|
||||||
if (e.name == 'NS_ERROR_ILLEGAL_VALUE') {
|
|
||||||
Zotero.debug(params, 1);
|
|
||||||
}
|
|
||||||
else if (e.name != 'NS_ERROR_FAILURE') {
|
|
||||||
Zotero.logError(e);
|
|
||||||
}
|
|
||||||
throw new Error('Localized string not available for ' + name);
|
|
||||||
}
|
|
||||||
return l10n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines property on the object
|
* Defines property on the object
|
||||||
* More compact way to do Object.defineProperty
|
* More compact way to do Object.defineProperty
|
||||||
|
|
|
@ -33,6 +33,7 @@ const Ci = Components.interfaces;
|
||||||
/** XPCOM files to be loaded for all modes **/
|
/** XPCOM files to be loaded for all modes **/
|
||||||
const xpcomFilesAll = [
|
const xpcomFilesAll = [
|
||||||
'zotero',
|
'zotero',
|
||||||
|
'intl',
|
||||||
'prefs',
|
'prefs',
|
||||||
'dataDirectory',
|
'dataDirectory',
|
||||||
'date',
|
'date',
|
||||||
|
|
Loading…
Add table
Reference in a new issue