From da5b1c757973d512f62639a02e22bc39fe4d81f6 Mon Sep 17 00:00:00 2001 From: boomzero Date: Tue, 6 Oct 2026 10:00:14 +0800 Subject: [PATCH 1/9] Address review findings from the 3.9.0 release PR - Close the expanded mobile menu before jumping to a section so the heading is not hidden behind it. - Privacy notice: script settings live in the site's localStorage and may be cloud-synced; the messages.html session is sent with requests. - Child protection: messages are not end-to-end encrypted. - Make the English classic-page language test set XMOJ_LANG=en, and count every evaluation of the native history script in the profile fixture so re-execution is detectable. - 3.8.8 release notes as HTML, since Notes is inserted with innerHTML. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E5dr7XTsCeoamqLSiT9rLp --- Update.json | 2 +- child-protection.html | 2 +- privacy.html | 6 +++--- site.js | 17 +++++++++++++++++ tests/chinese-language.test.cjs | 6 +++--- tests/fixtures/profile.html | 2 +- tests/profile-page.test.cjs | 2 +- 7 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Update.json b/Update.json index a9b9faee..926f44f0 100644 --- a/Update.json +++ b/Update.json @@ -3904,7 +3904,7 @@ "Description": "Fix image enlarger and minimalist skin on video replay pages; add page title" } ], - "Notes": "- 修复回放视频进度条拖动球被当作图片放大的问题\n- 修复极简黑白界面下视频播放器按钮出现灰色方框的问题\n- 回放页面增加页面标题" + "Notes": "" }, "3.9.0": { "UpdateDate": 1791249917714, diff --git a/child-protection.html b/child-protection.html index f4b5f4a9..c883f3a4 100644 --- a/child-protection.html +++ b/child-protection.html @@ -62,7 +62,7 @@

我们收集得很少

请家长留意

申请删除

diff --git a/privacy.html b/privacy.html index a55f81d0..48c569f5 100644 --- a/privacy.html +++ b/privacy.html @@ -59,11 +59,11 @@

我们收集什么数据

本产品不面向欧盟居民。XMOJ-Script 主要面向小明的OJ用户,没有专门为欧盟、英国或瑞士的用户提供服务。

-

只留在你电脑上的

+

存在你浏览器里的

会发到我们服务器的

diff --git a/site.js b/site.js index dbac9c5c..bb00b4e8 100644 --- a/site.js +++ b/site.js @@ -75,6 +75,23 @@ SelectBrowser(browser); } + // 手机上展开的菜单占据页面高度:先收起菜单,再跳到对应章节,标题才不会被导航栏挡住 + const siteNav = document.getElementById("SiteNav"); + if (siteNav && window.bootstrap) { + siteNav.addEventListener("click", (event) => { + const link = event.target.closest("a[href]"); + if (!link || !link.hash || link.pathname !== location.pathname || !siteNav.classList.contains("show")) return; + const target = document.getElementById(link.hash.slice(1)); + if (!target) return; + event.preventDefault(); + siteNav.addEventListener("hidden.bs.collapse", () => { + history.pushState(null, "", link.hash); + target.scrollIntoView(); + }, {once: true}); + bootstrap.Collapse.getOrCreateInstance(siteNav).hide(); + }); + } + const versionElements = document.querySelectorAll("[data-latest-version]"); if (versionElements.length > 0) { fetch("Update.json", {cache: "no-cache"}) diff --git a/tests/chinese-language.test.cjs b/tests/chinese-language.test.cjs index 3db28d04..6a11d576 100644 --- a/tests/chinese-language.test.cjs +++ b/tests/chinese-language.test.cjs @@ -14,7 +14,7 @@ const language = Between('function InitializeChineseLanguage(', '// The /web app const route = Between('function IsContestWebApp(', 'function GetContestRoute('); // Check reload behavior without navigating a real page away from its assertions. -function Context({cookie = '', pathname = '/problem.php', english = false, fail = false} = {}) { +function Context({cookie = '', pathname = '/problem.php', fail = false} = {}) { const storage = new Map(); const requests = []; const nodes = []; @@ -32,7 +32,7 @@ function Context({cookie = '', pathname = '/problem.php', english = false, fail document: { cookie, documentElement: {}, head: {appendChild: node => nodes.push(node)}, body: {prepend: node => nodes.push(node)}, getElementById: id => nodes.find(node => node.id === id), - querySelectorAll: () => [], querySelector: () => english ? {} : null, + querySelectorAll: () => [], querySelector: () => null, createElement: () => ({appendChild() {}, addEventListener() {}}) } }); @@ -52,7 +52,7 @@ test('forces the web cookie before requests and reloads an existing English app }); test('classic English pages do not call the broken language endpoint or reload', async () => { - const {scope, requests, reloads} = Context({english: true}); + const {scope, requests, reloads} = Context({cookie: 'XMOJ_LANG=en'}); assert.equal(await scope.EnsureChinesePage(), false); assert.equal(scope.document.documentElement.lang, 'zh-CN'); assert.equal(requests.length, 0); diff --git a/tests/fixtures/profile.html b/tests/fixtures/profile.html index 6c3812ab..27659e64 100644 --- a/tests/fixtures/profile.html +++ b/tests/fixtures/profile.html @@ -20,8 +20,8 @@