mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-14 21:28:11 +02:00
Don't bundle the en.json strings anymore, Promisify locale loading
(re: #4994)
This commit is contained in:
@@ -1,2 +1 @@
|
||||
export { dataLocales } from './locales.json';
|
||||
export { en as dataEn } from '../dist/locales/en.json';
|
||||
|
||||
File diff suppressed because one or more lines are too long
+72
-67
@@ -4,13 +4,13 @@ import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { json as d3_json } from 'd3-fetch';
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
|
||||
import { t, currentLocale, addTranslation, setLocale } from '../util/locale';
|
||||
import { t, localeStrings, setLocale } from '../util/locale';
|
||||
|
||||
import { coreData } from './data';
|
||||
import { coreHistory } from './history';
|
||||
import { coreValidator } from './validator';
|
||||
import { coreUploader } from './uploader';
|
||||
import { dataLocales, dataEn } from '../../data';
|
||||
import { dataLocales } from '../../data';
|
||||
import { geoRawMercator } from '../geo/raw_mercator';
|
||||
import { modeSelect } from '../modes/select';
|
||||
import { osmSetAreaKeys, osmSetPointTags, osmSetVertexTags } from '../osm/tags';
|
||||
@@ -30,29 +30,29 @@ export function coreContext() {
|
||||
context.version = '2.17.2';
|
||||
context.privacyVersion = '20191217';
|
||||
|
||||
// create a special translation that contains the keys in place of the strings
|
||||
let tkeys = JSON.parse(JSON.stringify(dataEn)); // clone deep
|
||||
let parents = [];
|
||||
// // create a special translation that contains the keys in place of the strings
|
||||
// let tkeys = JSON.parse(JSON.stringify(dataEn)); // clone deep
|
||||
// let parents = [];
|
||||
|
||||
function traverser(v, k, obj) {
|
||||
parents.push(k);
|
||||
if (typeof v === 'object') {
|
||||
forOwn(v, traverser);
|
||||
} else if (typeof v === 'string') {
|
||||
obj[k] = parents.join('.');
|
||||
}
|
||||
parents.pop();
|
||||
}
|
||||
// function traverser(v, k, obj) {
|
||||
// parents.push(k);
|
||||
// if (typeof v === 'object') {
|
||||
// forOwn(v, traverser);
|
||||
// } else if (typeof v === 'string') {
|
||||
// obj[k] = parents.join('.');
|
||||
// }
|
||||
// parents.pop();
|
||||
// }
|
||||
|
||||
function forOwn(obj, fn) {
|
||||
Object.keys(obj).forEach(k => fn(obj[k], k, obj));
|
||||
}
|
||||
// function forOwn(obj, fn) {
|
||||
// Object.keys(obj).forEach(k => fn(obj[k], k, obj));
|
||||
// }
|
||||
|
||||
forOwn(tkeys, traverser);
|
||||
addTranslation('_tkeys_', tkeys);
|
||||
// forOwn(tkeys, traverser);
|
||||
// addLocale('_tkeys_', tkeys);
|
||||
|
||||
addTranslation('en', dataEn);
|
||||
setLocale('en');
|
||||
// addLocale('en', dataEn);
|
||||
// setLocale('en');
|
||||
|
||||
|
||||
// https://github.com/openstreetmap/iD/issues/772
|
||||
@@ -231,6 +231,8 @@ export function coreContext() {
|
||||
return context;
|
||||
};
|
||||
|
||||
// Immediately save the user's history to localstorage, if possible
|
||||
// This is called someteimes, but also on the `window.onbeforeunload` handler
|
||||
context.save = () => {
|
||||
// no history save, no message onbeforeunload
|
||||
if (_inIntro || d3_select('.modal').size()) return;
|
||||
@@ -260,6 +262,18 @@ export function coreContext() {
|
||||
}
|
||||
};
|
||||
|
||||
// Debounce save, since it's a synchronous localStorage write,
|
||||
// and history changes can happen frequently (e.g. when dragging).
|
||||
context.debouncedSave = _debounce(context.save, 350);
|
||||
|
||||
function withDebouncedSave(fn) {
|
||||
return function() {
|
||||
const result = fn.apply(_history, arguments);
|
||||
context.debouncedSave();
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/* Graph */
|
||||
context.hasEntity = (id) => _history.graph().hasEntity(id);
|
||||
@@ -417,38 +431,34 @@ export function coreContext() {
|
||||
context.imagePath = (val) => context.asset(`img/${val}`);
|
||||
|
||||
|
||||
/* locales */
|
||||
// `locale` letiable contains a "requested locale".
|
||||
// It won't become the `currentLocale` until after loadLocale() is called.
|
||||
let _locale, _localePath;
|
||||
/* Locales */
|
||||
// Returns a Promise to load the strings for the given locale
|
||||
context.loadLocale = (requested) => {
|
||||
let locale = requested;
|
||||
|
||||
context.locale = function(loc, path) {
|
||||
if (!arguments.length) return currentLocale;
|
||||
_locale = loc;
|
||||
_localePath = path;
|
||||
return context;
|
||||
};
|
||||
|
||||
context.loadLocale = (callback) => {
|
||||
if (_locale && _locale !== 'en' && dataLocales.hasOwnProperty(_locale)) {
|
||||
_localePath = _localePath || context.asset(`locales/${_locale}.json`);
|
||||
d3_json(_localePath)
|
||||
.then(result => {
|
||||
addTranslation(_locale, result[_locale]);
|
||||
setLocale(_locale);
|
||||
utilDetect(true);
|
||||
if (callback) callback();
|
||||
})
|
||||
.catch(err => {
|
||||
if (callback) callback(err.message);
|
||||
});
|
||||
} else {
|
||||
if (_locale) {
|
||||
setLocale(_locale);
|
||||
utilDetect(true);
|
||||
}
|
||||
if (callback) callback();
|
||||
if (!_data) {
|
||||
return Promise.reject('loadLocale called before init');
|
||||
}
|
||||
if (!dataLocales.hasOwnProperty(locale)) { // Not supported, e.g. 'es-FAKE'
|
||||
locale = locale.split('-')[0]; // Fallback to the first part 'es'
|
||||
}
|
||||
if (!dataLocales.hasOwnProperty(locale)) {
|
||||
return Promise.reject(`Unsupported locale: ${requested}`);
|
||||
}
|
||||
|
||||
if (localeStrings[locale]) { // already loaded
|
||||
return Promise.resolve(locale);
|
||||
}
|
||||
|
||||
let fileMap = _data.fileMap();
|
||||
const key = `locale_${locale}`;
|
||||
fileMap[key] = `locales/${locale}.json`; // .min.json?
|
||||
|
||||
return _data.get(key)
|
||||
.then(d => {
|
||||
localeStrings[locale] = d[locale];
|
||||
return locale;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -488,12 +498,18 @@ export function coreContext() {
|
||||
context.init = () => {
|
||||
const hash = utilStringQs(window.location.hash);
|
||||
|
||||
_locale = utilDetect().locale;
|
||||
if (_locale && !dataLocales.hasOwnProperty(_locale)) {
|
||||
_locale = _locale.split('-')[0];
|
||||
}
|
||||
|
||||
_data = coreData(context);
|
||||
|
||||
// always load the English locale, then load preferred locale.
|
||||
const requested = utilDetect().locale;
|
||||
context.loadLocale('en')
|
||||
.then(() => context.loadLocale(requested))
|
||||
.then(received => { // `received` may not match `requested`.
|
||||
setLocale(received); // (e.g. 'es-FAKE' will return 'es')
|
||||
utilDetect(true); // Then force redetection
|
||||
})
|
||||
.catch(err => console.error(err)); // eslint-disable-line
|
||||
|
||||
_history = coreHistory(context);
|
||||
_validator = coreValidator(context);
|
||||
_uploader = coreUploader(context);
|
||||
@@ -504,17 +520,6 @@ export function coreContext() {
|
||||
context.pauseChangeDispatch = _history.pauseChangeDispatch;
|
||||
context.resumeChangeDispatch = _history.resumeChangeDispatch;
|
||||
|
||||
// Debounce save, since it's a synchronous localStorage write,
|
||||
// and history changes can happen frequently (e.g. when dragging).
|
||||
context.debouncedSave = _debounce(context.save, 350);
|
||||
function withDebouncedSave(fn) {
|
||||
return function() {
|
||||
const result = fn.apply(_history, arguments);
|
||||
context.debouncedSave();
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
context.perform = withDebouncedSave(_history.perform);
|
||||
context.replace = withDebouncedSave(_history.replace);
|
||||
context.pop = withDebouncedSave(_history.pop);
|
||||
|
||||
+33
-14
@@ -4,13 +4,15 @@ import {
|
||||
selectAll as d3_selectAll
|
||||
} from 'd3-selection';
|
||||
|
||||
import { t, textDirection } from '../util/locale';
|
||||
import { t, textDirection, setLocale } from '../util/locale';
|
||||
|
||||
import { tooltip } from '../util/tooltip';
|
||||
|
||||
import { behaviorHash } from '../behavior';
|
||||
import { modeBrowse } from '../modes/browse';
|
||||
import { svgDefs, svgIcon } from '../svg';
|
||||
import { utilGetDimensions } from '../util/dimensions';
|
||||
import { utilDetect } from '../util/detect';
|
||||
|
||||
import { uiAccount } from './account';
|
||||
import { uiAttribution } from './attribution';
|
||||
@@ -337,31 +339,48 @@ export function uiInit(context) {
|
||||
}
|
||||
|
||||
|
||||
// `ui()` renders the iD interface into the given node, assigning
|
||||
// that node as the `container`. We need to delay rendering until
|
||||
// the locale has been loaded (i.e. promise settled), because the
|
||||
// UI code expects localized strings to be available.
|
||||
function ui(node, callback) {
|
||||
_initCallback = callback;
|
||||
var container = d3_select(node);
|
||||
context.container(container);
|
||||
context.loadLocale(function(err) {
|
||||
if (!err) {
|
||||
|
||||
const current = utilDetect().locale;
|
||||
context.loadLocale(current)
|
||||
.then(function() {
|
||||
render(container);
|
||||
}
|
||||
if (callback) {
|
||||
callback(err);
|
||||
}
|
||||
});
|
||||
if (callback) callback();
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error(err); // eslint-disable-line
|
||||
if (callback) callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
ui.restart = function(arg) {
|
||||
// `ui.restart()` will destroy and rebuild the entire iD interface,
|
||||
// for example to switch the locale while iD is running.
|
||||
ui.restart = function(locale) {
|
||||
context.keybinding().clear();
|
||||
context.locale(arg);
|
||||
context.loadLocale(function(err) {
|
||||
if (!err) {
|
||||
|
||||
var requested = locale || utilDetect().locale;
|
||||
context.loadLocale(requested)
|
||||
.then(function(received) { // `received` may not match `requested`.
|
||||
setLocale(received); // (e.g. 'es-FAKE' will return 'es')
|
||||
utilDetect(true); // Then force redetection
|
||||
|
||||
context.container().selectAll('*').remove();
|
||||
render(context.container());
|
||||
|
||||
if (_initCallback) _initCallback();
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error(err); // eslint-disable-line
|
||||
if (_initCallback) _initCallback(err);
|
||||
});
|
||||
};
|
||||
|
||||
ui.sidebar = uiSidebar(context);
|
||||
|
||||
+22
-17
@@ -1,21 +1,26 @@
|
||||
let _translations = Object.create(null);
|
||||
let _dataLanguages = {};
|
||||
|
||||
export let currentLocale = 'en';
|
||||
|
||||
// `localeStrings` is an object containing all loaded locale codes -> string data
|
||||
// {
|
||||
// en: {icons: {…}, toolbar: {…}, modes: {…}, operations: {…}, …},
|
||||
// de: {icons: {…}, toolbar: {…}, modes: {…}, operations: {…}, …},
|
||||
// …
|
||||
// }
|
||||
export let localeStrings = Object.create(null);
|
||||
|
||||
export let currentLocale;
|
||||
export let textDirection = 'ltr';
|
||||
export let languageNames = {};
|
||||
export let scriptNames = {};
|
||||
|
||||
export function setLocale(val) {
|
||||
if (_translations[val] !== undefined) {
|
||||
currentLocale = val;
|
||||
} else if (_translations[val.split('-')[0]]) {
|
||||
currentLocale = val.split('-')[0];
|
||||
}
|
||||
}
|
||||
|
||||
export function addTranslation(id, value) {
|
||||
_translations[id] = value;
|
||||
export function setLocale(locale) {
|
||||
currentLocale = locale;
|
||||
// if (localeStrings[locale] !== undefined) {
|
||||
// currentLocale = locale;
|
||||
// } else if (localeStrings[locale.split('-')[0]]) {
|
||||
// currentLocale = locale.split('-')[0];
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,10 +28,10 @@ export function addTranslation(id, value) {
|
||||
* language, and return it. This function will be called recursively
|
||||
* with locale `en` if a string can not be found in the requested language.
|
||||
*
|
||||
* @param {string} s string identifier
|
||||
* @param {object?} replacements token replacements and default string
|
||||
* @param {string?} locale locale to use (defaults to currentLocale)
|
||||
* @returns {string?} localized string
|
||||
* @param {string} s string identifier
|
||||
* @param {object?} replacements token replacements and default string
|
||||
* @param {string?} locale locale to use (defaults to currentLocale)
|
||||
* @return {string?} localized string
|
||||
*/
|
||||
export function t(s, replacements, locale) {
|
||||
locale = locale || currentLocale;
|
||||
@@ -36,7 +41,7 @@ export function t(s, replacements, locale) {
|
||||
.map(s => s.replace(/<TX_DOT>/g, '.'))
|
||||
.reverse();
|
||||
|
||||
let result = _translations[locale];
|
||||
let result = localeStrings[locale];
|
||||
|
||||
while (result !== undefined && path.length) {
|
||||
result = result[path.pop()];
|
||||
|
||||
Reference in New Issue
Block a user