Update Site source
This commit is contained in:
1 parent
223ad634d7
commit
ca116d6cce
8 files changed
+94
-34
No files matched your search
+1
-1
@@ -8,7 +8,7 @@ const meta = new URL("../dist/.openai/", import.meta.url);
|
||||
await rm(dist, { recursive: true, force: true });
|
||||
await Promise.all([mkdir(server, { recursive: true }), mkdir(meta, { recursive: true })]);
|
||||
const [rawIndexHtml, addonsJs, bootGuardJs, i18nJs, tasksJs, calendarJs, i18nRenderersJs, manifest, serviceWorker, icon, localeEn, localeZh] = await Promise.all([text("index.html"), text("addons.js"), text("boot-guard.js"), text("i18n.js"), text("tasks.js"), text("calendar.js"), text("i18n-renderers.js"), text("manifest.webmanifest"), text("service-worker.js"), text("life-os-icon.svg"), readFile(new URL("../public/locales/en.json", import.meta.url), "utf8"), readFile(new URL("../public/locales/zh-CN.json", import.meta.url), "utf8")]);
|
||||
const release = "1.5.3";
|
||||
const release = "1.5.4";
|
||||
const indexHtml = rawIndexHtml.replace('src="addons.js"', `src="addons.js?v=${release}`).replace('src="tasks.js"', `src="tasks.js?v=${release}`).replace('src="calendar.js"', `src="calendar.js?v=${release}`);
|
||||
await writeFile(new URL("assets.js", server), `export const indexHtml=${JSON.stringify(indexHtml)};\nexport const addonsJs=${JSON.stringify(addonsJs)};\nexport const bootGuardJs=${JSON.stringify(bootGuardJs)};\nexport const i18nJs=${JSON.stringify(i18nJs)};\nexport const localeEn=JSON.parse(${JSON.stringify(localeEn)});\nexport const localeZh=JSON.parse(${JSON.stringify(localeZh)});\nexport const localeEnJs=${JSON.stringify(`window.LifeOSLocales=window.LifeOSLocales||{};window.LifeOSLocales.en=${localeEn};`)};\nexport const localeZhJs=${JSON.stringify(`window.LifeOSLocales=window.LifeOSLocales||{};window.LifeOSLocales['zh-CN']=${localeZh};`)};\nexport const tasksJs=${JSON.stringify(tasksJs)};\nexport const calendarJs=${JSON.stringify(calendarJs)};\nexport const i18nRenderersJs=${JSON.stringify(i18nRenderersJs)};\nexport const manifest=${JSON.stringify(manifest)};\nexport const serviceWorker=${JSON.stringify(serviceWorker)};\nexport const icon=${JSON.stringify(icon)};\n`);
|
||||
await copyFile(new URL("../worker/index.js", import.meta.url), new URL("index.js", server));
|
||||
|
||||
+48
-14
@@ -38,22 +38,56 @@ for (const [, inlineScript] of source.matchAll(/<script>([\s\S]*?)<\/script>/g))
|
||||
assert.doesNotMatch(source, /localizeDynamicText|createTreeWalker|NodeFilter\.SHOW_TEXT|const ZH=/);
|
||||
assert.match(source, /id==='system'\)window\.systemApp\(c\)/);
|
||||
assert.match(source, /id==='today'\)window\.today\(c\)/);
|
||||
assert.match(assets.i18nRenderersJs, /window\.setLanguage = value/);
|
||||
assert.match(assets.i18nJs, /window\.setLanguage = setLanguage/);
|
||||
assert.match(assets.i18nRenderersJs, /window\.renderAll\(\)/);
|
||||
assert.doesNotMatch(source, /Version 0\.1|Schema v1/);
|
||||
const langSource = source.match(/function browserLanguage\(\).*?function i18n\(key/)[0].replace(/function i18n\(key[\s\S]*$/, "");
|
||||
let preferences = { language: "auto", languageMode: "auto" };
|
||||
const languageContext = vm.createContext({ navigator: { languages: ["zh-CN"], language: "zh-CN" }, settings: () => preferences });
|
||||
vm.runInContext(langSource, languageContext);
|
||||
assert.equal(languageContext.lang(), "zh", "auto mode follows Chinese browser language");
|
||||
languageContext.navigator.languages = ["en-US"];
|
||||
assert.equal(languageContext.lang(), "en", "auto mode follows English browser language");
|
||||
preferences = { language: "zh", languageMode: "manual" };
|
||||
assert.equal(languageContext.lang(), "zh", "manual Chinese choice overrides browser language");
|
||||
preferences = { language: "en", languageMode: "manual" };
|
||||
assert.equal(languageContext.lang(), "en", "manual English choice overrides browser language");
|
||||
preferences = { language: "zh" };
|
||||
assert.equal(languageContext.lang(), "zh", "legacy manual preference survives settings migration");
|
||||
const makeStorage = initial => {
|
||||
const values = new Map(Object.entries(initial || {}));
|
||||
return { getItem: key => values.get(key) ?? null, setItem: (key,value) => values.set(key,String(value)), values };
|
||||
};
|
||||
let legacySettings = { language: "auto", languageMode: "auto" };
|
||||
const calls = { icons: 0, render: 0, apply: 0, toast: 0 };
|
||||
const localStorage = makeStorage();
|
||||
const localeContext = vm.createContext({
|
||||
navigator: { languages: ["zh-CN"], language: "zh-CN" },
|
||||
localStorage,
|
||||
LifeOSLocales: { en: assets.localeEn, "zh-CN": assets.localeZh },
|
||||
settings: () => legacySettings,
|
||||
renderIcons() { calls.icons++; }, renderAll() { calls.render++; }, applyLanguage() { calls.apply++; }, toast() { calls.toast++; },
|
||||
});
|
||||
localeContext.window = localeContext;
|
||||
vm.runInContext(assets.i18nJs, localeContext);
|
||||
assert.equal(localeContext.LifeI18n.preference(), "auto");
|
||||
assert.equal(localeContext.LifeI18n.language(), "zh", "auto mode follows Chinese browser language");
|
||||
localeContext.navigator.languages = ["en-US"];
|
||||
assert.equal(localeContext.LifeI18n.language(), "en", "auto mode follows English browser language");
|
||||
assert.equal(localeContext.LifeI18n.t("app.today"), "TODAY");
|
||||
localeContext.setLanguage("zh");
|
||||
assert.equal(localeContext.LifeI18n.language(), "zh", "manual Chinese choice overrides browser language");
|
||||
assert.equal(localeContext.LifeI18n.t("app.today"), "今日");
|
||||
assert.equal(localStorage.getItem("lifeos_language_preference_v1"), "zh");
|
||||
assert.deepEqual(calls, { icons: 1, render: 1, apply: 1, toast: 1 }, "language selection redraws the desktop and shows feedback");
|
||||
legacySettings = { language: "en", languageMode: "manual" };
|
||||
assert.equal(localeContext.LifeI18n.language(), "zh", "cloud settings cannot overwrite the local manual choice");
|
||||
localeContext.setLanguage("en");
|
||||
assert.equal(localeContext.LifeI18n.language(), "en", "manual English choice overrides browser language");
|
||||
assert.equal(localeContext.LifeI18n.t("app.today"), "TODAY");
|
||||
localeContext.navigator.languages = ["zh-CN"];
|
||||
localeContext.setLanguage("auto");
|
||||
assert.equal(localeContext.LifeI18n.preference(), "auto");
|
||||
assert.equal(localeContext.LifeI18n.language(), "zh", "auto mode ignores stale cloud preference and follows this device");
|
||||
const migratedStorage = makeStorage({ lifeos_settings: JSON.stringify({ language: "zh" }) });
|
||||
const migratedContext = vm.createContext({
|
||||
navigator: { languages: ["en-US"] }, localStorage: migratedStorage,
|
||||
LifeOSLocales: { en: assets.localeEn, "zh-CN": assets.localeZh },
|
||||
settings: () => ({ language: "zh", languageMode: "manual" }),
|
||||
});
|
||||
migratedContext.window = migratedContext;
|
||||
vm.runInContext(assets.i18nJs, migratedContext);
|
||||
assert.equal(migratedContext.LifeI18n.language(), "zh", "legacy manual preference migrates to the local preference key");
|
||||
assert.match(assets.i18nRenderersJs, /preference === 'zh'/);
|
||||
assert.match(assets.i18nRenderersJs, /onclick=\"window\.setLanguage\('zh'\)\"/);
|
||||
assert.doesNotMatch(assets.addonsJs, /lifeos_language_preference_v1/, "the device locale preference stays outside cloud-synced keys");
|
||||
const zhLogin = await worker.default.fetch(new Request("https://life-os.test/", { headers: { "accept-language": "zh-CN,zh;q=0.9" } }), {});
|
||||
assert.match(await zhLogin.text(), /登录 ChatGPT/);
|
||||
const enLogin = await worker.default.fetch(new Request("https://life-os.test/", { headers: { "accept-language": "en-US,en;q=0.9" } }), {});
|
||||
|
||||
Reference in new issue
Block a user