diff --git a/js/ide.ts b/js/ide.ts
index eac2b205..55441c56 100644
--- a/js/ide.ts
+++ b/js/ide.ts
@@ -203,7 +203,9 @@ class IDE {
if (typeof abortCallback == "function") {
this.onAbort = abortCallback;
const aborter = $(
- ' (abort)'
+ ` (${i18n.t(
+ "waiter.abort"
+ )})`
).on("click", () => {
this.abort();
return false;
@@ -214,7 +216,7 @@ class IDE {
}
abort() {
if (typeof this.onAbort == "function") {
- this.addInfo("aborting");
+ this.addInfo(i18n.t("waiter.aborting"));
this.onAbort(this.close);
}
}
@@ -269,7 +271,7 @@ class IDE {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const ide = this;
// parse url string parameters
- ide.waiter.addInfo("parse url parameters");
+ ide.waiter.addInfo(i18n.t("waiter.parse_url_parameters"));
const args = urlParameters();
// set appropriate settings
if (args.has_coords) {
@@ -287,7 +289,7 @@ class IDE {
}
settings.save();
- ide.waiter.addInfo("initialize page");
+ ide.waiter.addInfo(i18n.t("waiter.initialize_page"));
// init page layout
const isInitialAspectPortrait =
$(window).width() / $(window).height() < 0.8;
@@ -468,7 +470,7 @@ class IDE {
}
// init dataviewer
ide.dataViewer = CodeMirror($("#data")[0], {
- value: "no data loaded yet",
+ value: i18n.t("editor.no_data_loaded"),
lineNumbers: true,
readOnly: true,
mode: "javascript"
@@ -865,7 +867,7 @@ class IDE {
const isCountPresent = /out[^;]+?count/.test(query);
// show warning/info if only invisible data is returned and 'out...count' is not present in the query
- if (empty_msg == "no visible data") {
+ if (empty_msg == "waiter.no_visible_data") {
if (!isCountPresent && !settings.no_autorepair) {
const content = `
${i18n.t(
"warning.incomplete.expl.1"
@@ -905,16 +907,16 @@ class IDE {
}
}
// auto tab switching (if only areas are returned)
- if (empty_msg == "only areas returned") ide.switchTab("Data");
+ if (empty_msg == "waiter.only_areas_returned") ide.switchTab("Data");
// auto tab switching (if nodes without coordinates are returned)
- if (empty_msg == "no coordinates returned") ide.switchTab("Data");
+ if (empty_msg == "waiter.no_coordinates_returned") ide.switchTab("Data");
// auto tab switching (if unstructured data is returned)
if (data_mode == "unknown") ide.switchTab("Data");
// display empty map badge
$(
`
${i18n.t(
"map.intentionally_blank"
- )} (${empty_msg})
`
+ )} (${i18n.t(empty_msg)})`
).appendTo("#map");
};
overpass.handlers["onDataReceived"] = function (
@@ -2211,14 +2213,14 @@ class IDE {
// 1. render canvas from map tiles
// hide map controlls in this step :/
// todo: also hide popups?
- this.waiter.addInfo("prepare map");
+ this.waiter.addInfo(i18n.t("waiter.prepare_map"));
$("#map .leaflet-control-container .leaflet-top").hide();
$("#data_stats").hide();
if (settings.export_image_attribution)
this.map.addControl(this.attribControl);
if (!settings.export_image_scale) this.map.removeControl(this.scaleControl);
// try to use crossOrigin image loading. osm tiles should be served with the appropriate headers -> no need of bothering the proxy
- this.waiter.addInfo("rendering map tiles");
+ this.waiter.addInfo(i18n.t("waiter.rendering_map_tiles"));
$("#map .leaflet-overlay-pane").hide();
const canvas = await html2canvas(document.getElementById("map"), {
useCORS: true,
@@ -2231,7 +2233,7 @@ class IDE {
if (!settings.export_image_scale) this.map.addControl(this.scaleControl);
if (settings.show_data_stats) $("#data_stats").show();
$("#map .leaflet-control-container .leaflet-top").show();
- this.waiter.addInfo("rendering map data");
+ this.waiter.addInfo(i18n.t("waiter.rendering_map_data"));
// 2. render overlay data onto canvas
canvas.id = "render_canvas";
const ctx = canvas.getContext("2d");
@@ -2257,7 +2259,7 @@ class IDE {
});
v.render();
}
- this.waiter.addInfo("converting to png image");
+ this.waiter.addInfo(i18n.t("waiter.converting_to_png_image"));
// 3. export canvas as html image
const imgstr = canvas.toDataURL("image/png");
let attrib_message = "";
@@ -2585,7 +2587,7 @@ class IDE {
}
async update_map() {
this.waiter.open(i18n.t("waiter.processing_query"));
- this.waiter.addInfo("resetting map");
+ this.waiter.addInfo(i18n.t("waiter.resetting_map"));
$("#data_stats").remove();
// resets previously highlighted error lines
this.resetErrors();
@@ -2595,7 +2597,7 @@ class IDE {
this.map.removeLayer(overpass.osmLayer);
$("#map_blank").remove();
- this.waiter.addInfo("building query");
+ this.waiter.addInfo(i18n.t("waiter.building_query"));
// run the query via the overpass object
const query = await this.getQuery();
if (configs.push_history_url && typeof history.pushState == "function") {
diff --git a/js/overpass.ts b/js/overpass.ts
index 861e849d..7bd0a4ac 100644
--- a/js/overpass.ts
+++ b/js/overpass.ts
@@ -7,6 +7,7 @@ import L_OSM4Leaflet from "./OSM4Leaflet";
import L_GeoJsonNoVanish from "./GeoJsonNoVanish";
import configs from "./configs";
+import i18n from "./i18n";
import settings from "./settings";
import {htmlentities} from "./misc";
import styleparser from "./jsmapcss";
@@ -80,21 +81,17 @@ class Overpass {
query = `${query}`;
}
}
- overpass.fire(
- "onProgress",
- "calling Overpass API interpreter",
- (callback) => {
- // kill the query on abort
- overpass.ajax_request.abort();
- // try to abort queries via kill_my_queries
- $.get(`${server}kill_my_queries`)
- .done(callback)
- .fail(() => {
- console.log("Warning: failed to kill query.");
- callback();
- });
- }
- );
+ overpass.fire("onProgress", i18n.t("waiter.calling_api"), (callback) => {
+ // kill the query on abort
+ overpass.ajax_request.abort();
+ // try to abort queries via kill_my_queries
+ $.get(`${server}kill_my_queries`)
+ .done(callback)
+ .fail(() => {
+ console.log("Warning: failed to kill query.");
+ callback();
+ });
+ });
function onSuccessCb(data, textStatus, jqXHR) {
//textStatus is not needed in the successCallback, don't cache it
if (cache) cache[query] = [data, undefined, jqXHR];
@@ -105,10 +102,15 @@ class Overpass {
const scale = Math.floor(Math.log(data_amount) / Math.log(10));
data_amount =
Math.round(data_amount / Math.pow(10, scale)) * Math.pow(10, scale);
- if (data_amount < 1000) data_txt = `${data_amount} bytes`;
- else if (data_amount < 1000000) data_txt = `${data_amount / 1000} kB`;
- else data_txt = `${data_amount / 1000000} MB`;
- overpass.fire("onProgress", `received about ${data_txt} of data`);
+ if (data_amount < 1000)
+ data_txt = `${data_amount} ${i18n.t("waiter.bytes")}`;
+ else if (data_amount < 1000000)
+ data_txt = `${data_amount / 1000} ${i18n.t("waiter.kilobytes")}`;
+ else data_txt = `${data_amount / 1000000} ${i18n.t("waiter.megabytes")}`;
+ overpass.fire(
+ "onProgress",
+ i18n.t("waiter.received_data").replace("{{data_amount}}", data_txt)
+ );
overpass.fire(
"onDataReceived",
data_amount,
@@ -138,7 +140,7 @@ class Overpass {
};
overpass.ajax_request_duration =
Date.now() - overpass.ajax_request_start;
- overpass.fire("onProgress", "parsing data");
+ overpass.fire("onProgress", i18n.t("waiter.parsing_data"));
setTimeout(() => {
// hacky firefox hack :( (it is not properly detecting json from the content-type header)
if (typeof data == "string" && data[0] == "{") {
@@ -418,7 +420,7 @@ class Overpass {
overpass.osmLayer = new L_OSM4Leaflet(null, {
afterParse() {
- overpass.fire("onProgress", "rendering geoJSON");
+ overpass.fire("onProgress", i18n.t("waiter.rendering"));
},
baseLayerClass: L_GeoJsonNoVanish,
baseLayerOptions: {
@@ -631,7 +633,10 @@ class Overpass {
if (!shouldCacheOnly) overpass.fire("onGeoJsonReady");
// print raw data
- overpass.fire("onProgress", "printing raw data");
+ overpass.fire(
+ "onProgress",
+ i18n.t("waiter.printing_raw_data")
+ );
setTimeout(() => {
overpass.resultText = jqXHR.responseText;
overpass.fire("onRawDataPresent");
@@ -657,7 +662,7 @@ class Overpass {
.children()
.not("note,meta,bounds,area").length == 0)
)
- empty_msg = "only areas returned";
+ empty_msg = "waiter.only_areas_returned";
else if (
(data_mode == "json" &&
_.some(data.elements, {type: "node"})) ||
@@ -665,7 +670,7 @@ class Overpass {
$("osm", data).children().filter("node").length > 0)
)
// check for "ids_only" or "tags" on nodes
- empty_msg = "no coordinates returned";
+ empty_msg = "waiter.no_coordinates_returned";
else if (
(data_mode == "json" &&
_.some(data.elements, {type: "way"}) &&
@@ -683,7 +688,7 @@ class Overpass {
.filter("nd").length == 0)
)
// check for "ids_only" or "tags" on ways
- empty_msg = "no coordinates returned";
+ empty_msg = "waiter.no_coordinates_returned";
else if (
(data_mode == "json" &&
_.some(data.elements, {type: "relation"}) &&
@@ -701,14 +706,14 @@ class Overpass {
.filter("member").length == 0)
)
// check for "ids_only" or "tags" on relations
- empty_msg = "no coordinates returned";
- else empty_msg = "no visible data";
+ empty_msg = "waiter.no_coordinates_returned";
+ else empty_msg = "waiter.no_visible_data";
} else if (data_mode == "error") {
- empty_msg = "an error occured";
+ empty_msg = "waiter.an_error_occured";
} else if (data_mode == "unknown") {
- empty_msg = "unstructured data returned";
+ empty_msg = "waiter.unstructured_data_returned";
} else {
- empty_msg = "received empty dataset";
+ empty_msg = "waiter.received_empty_dataset";
}
// show why there is an empty map
overpass.fire("onEmptyMap", empty_msg, data_mode);
@@ -736,7 +741,7 @@ class Overpass {
success: onSuccessCb,
error(jqXHR, textStatus) {
if (textStatus == "abort") return; // ignore aborted queries.
- overpass.fire("onProgress", "error during ajax call");
+ overpass.fire("onProgress", i18n.t("waiter.error_during_ajax_call"));
if (
jqXHR.status == 400 ||
jqXHR.status == 504 ||
@@ -750,17 +755,31 @@ class Overpass {
overpass.resultText = jqXHR.resultText;
let errmsg = "";
if (jqXHR.state() == "rejected")
- errmsg +=
- "Request rejected. (e.g. server not found, request blocked by browser addon, request redirected, internal server errors, etc.)
";
+ errmsg += "" + i18n.t("waiter.request_rejected") + "
";
if (textStatus == "parsererror")
- errmsg += "Error while parsing the data (parsererror).
";
+ errmsg +=
+ "" +
+ i18n
+ .t("waiter.parse_error")
+ .replace("{{textStatus}}", textStatus) +
+ "
";
else if (textStatus != "error" && textStatus != jqXHR.statusText)
- errmsg += `Error-Code: ${textStatus}
`;
+ errmsg +=
+ "" +
+ i18n
+ .t("waiter.error_code")
+ .replace("{{textStatus}}", textStatus) +
+ "
";
if (
(jqXHR.status != 0 && jqXHR.status != 200) ||
jqXHR.statusText != "OK" // note to me: jqXHR.status "should" give http status codes
)
- errmsg += `Error-Code: ${jqXHR.statusText} (${jqXHR.status})
`;
+ errmsg +=
+ "" +
+ i18n
+ .t("waiter.error_code")
+ .replace("{{textStatus}}", jqXHR.statusText) +
+ ` (${jqXHR.status})
`;
overpass.fire("onAjaxError", errmsg);
// closing wait spinner
overpass.fire("onDone");
diff --git a/js/popup.ts b/js/popup.ts
index d5fb7cd0..7c5f2b09 100644
--- a/js/popup.ts
+++ b/js/popup.ts
@@ -1,4 +1,5 @@
import $ from "jquery";
+import i18n from "./i18n";
import {htmlentities} from "./misc";
import tag2link from "tag2link/index.json";
@@ -10,19 +11,25 @@ export function featurePopupContent(feature: GeoJSON.Feature) {
let popup = "";
if (feature.properties.type == "node")
popup +=
- `Node` +
+ ``;
else if (feature.properties.type == "way")
popup +=
- `Way` +
+ ``;
else if (feature.properties.type == "relation")
popup +=
- `Relation` +
+ ``;
@@ -33,7 +40,9 @@ export function featurePopupContent(feature: GeoJSON.Feature) {
feature.properties.tags &&
!$.isEmptyObject(feature.properties.tags)
) {
- popup += `Tags`;
+ popup += `${i18n.t(
+ "tags"
+ )}`;
if (typeof Object.keys === "function") {
popup += ` ${
Object.keys(feature.properties.tags).length
@@ -107,7 +116,9 @@ export function featurePopupContent(feature: GeoJSON.Feature) {
feature.properties.relations &&
!$.isEmptyObject(feature.properties.relations)
) {
- popup += `Relations`;
+ popup += `${i18n.t(
+ "relations"
+ )}`;
if (typeof Object.keys === "function") {
popup += ` ${
Object.keys(feature.properties.relations).length
@@ -132,7 +143,9 @@ export function featurePopupContent(feature: GeoJSON.Feature) {
feature.properties.meta &&
!$.isEmptyObject(feature.properties.meta)
) {
- popup += `Metadata
`;
+ popup += `${i18n.t(
+ "metadata"
+ )}
`;
$.each(feature.properties.meta, (k, v) => {
k = htmlentities(k);
v = htmlentities(v);
@@ -149,7 +162,9 @@ export function featurePopupContent(feature: GeoJSON.Feature) {
const lat = feature.geometry.coordinates[1];
const lon = feature.geometry.coordinates[0];
popup +=
- `Coordinates
` +
+ `${i18n.t(
+ "coordinates"
+ )}
` +
`${lat} / ${lon} (lat/lon)
`;
}
if (
@@ -160,7 +175,9 @@ export function featurePopupContent(feature: GeoJSON.Feature) {
]) != -1
) {
if (feature.properties && feature.properties.tainted == true) {
- popup += `Attention: incomplete geometry (e.g. some nodes missing)
`;
+ popup += `${i18n.t(
+ "popup.incomplete_geometry"
+ )}
`;
}
}
return popup;
diff --git a/locales/en.json b/locales/en.json
index cd86a873..6e90fed3 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -262,9 +262,48 @@
"warning.huge_data.expl.1": "This query returned quite a lot of data (approx. {{amount_txt}}).",
"warning.huge_data.expl.2": "Your browser may have a hard time trying to render this. Do you really want to continue?",
+ "editor.no_data_loaded": "no data loaded yet",
+
"waiter.processing_query": "processing query...",
"waiter.export_as_image": "exporting as image...",
+ "waiter.calling_api": "Calling Overpass API interpreter",
+ "waiter.abort": "abort",
+ "waiter.aborting": "aborting",
+
+ "waiter.ide_starting_up": "ide starting up",
+ "waiter.load_settings": "load settings",
+ "waiter.translate_ui": "translate ui",
+ "waiter.parse_url_parameters": "parse url parameters",
+ "waiter.initialize_page": "initialize page",
+ "waiter.prepare_map": "prepare map",
+ "waiter.rendering_map_tiles": "rendering map tiles",
+ "waiter.rendering_map_data": "rendering map data",
+ "waiter.converting_to_png_image": "converting to png image",
+ "waiter.resetting_map": "resetting map",
+ "waiter.building_query": "building query",
+
+ "waiter.only_areas_returned": "only areas returned",
+ "waiter.no_coordinates_returned": "no coordinates returned",
+ "waiter.no_visible_data": "no visible data",
+ "waiter.an_error_occured": "an error occured",
+ "waiter.unstructured_data_returned": "unstructured data returned",
+ "waiter.received_empty_dataset": "received empty dataset",
+ "waiter.printing_raw_data": "printing raw data",
+ "waiter.error_during_ajax_call": "error during ajax call",
+
+ "waiter.bytes": "bytes",
+ "waiter.kilobytes": "kB",
+ "waiter.megabytes": "MB",
+ "waiter.received_data": "received about {{data_amount}} of data",
+
+ "waiter.parsing_data": "parsing data",
+ "waiter.rendering": "rendering geoJSON",
+
+ "waiter.request_rejected": "Request rejected. (e.g. server not found, request blocked by browser addon, request redirected, internal server errors, etc.)",
+ "waiter.parse_error": "Error while parsing the data ({{textStatus}}).",
+ "waiter.error_code": "Error-Code: {{textStatus}}",
+
"data_stats.loaded": "Loaded",
"data_stats.displayed": "Displayed",
"data_stats.nodes": "nodes",