summaryrefslogtreecommitdiff
path: root/src/ollama_web/static
diff options
context:
space:
mode:
Diffstat (limited to 'src/ollama_web/static')
-rw-r--r--src/ollama_web/static/i18n.js25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/ollama_web/static/i18n.js b/src/ollama_web/static/i18n.js
index 985b452..7f8d013 100644
--- a/src/ollama_web/static/i18n.js
+++ b/src/ollama_web/static/i18n.js
@@ -1,17 +1,35 @@
/** Small i18n helper for the browser.
*
- * The server injects ``window.I18N`` as a nested message object. This module
- * exposes ``t(key, fallback)`` to resolve dot-separated keys safely.
+ * The server stores the nested message object as JSON in a non-executable
+ * meta element. This module parses it and exposes ``t(key, fallback)`` to
+ * resolve dot-separated keys safely without requiring inline JavaScript.
*/
(function () {
"use strict";
+ const dataEl = document.querySelector('meta[name="ollama-web-i18n"]');
+ let messages = {};
+
+ if (!dataEl) {
+ console.error('i18n data element "ollama-web-i18n" was not found');
+ } else {
+ try {
+ const parsed = JSON.parse(dataEl.getAttribute("content") || "");
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
+ throw new TypeError("i18n data must be a JSON object");
+ }
+ messages = parsed;
+ } catch (err) {
+ console.error("failed to parse i18n data", err);
+ }
+ }
+
function t(key, fallback) {
if (typeof key !== "string") {
return fallback !== undefined ? fallback : String(key);
}
const parts = key.split(".");
- let current = window.I18N;
+ let current = messages;
for (const part of parts) {
if (current == null || typeof current !== "object" || !(part in current)) {
return fallback !== undefined ? fallback : key;
@@ -24,5 +42,6 @@
return fallback !== undefined ? fallback : key;
}
+ window.I18N = messages;
window.t = t;
})();