From 586d9169927557fe62e371d3f250de602bb3b779 Mon Sep 17 00:00:00 2001 From: boomzero Date: Sat, 19 Sep 2026 08:23:12 +0800 Subject: [PATCH 01/59] =?UTF-8?q?fix:=20=E6=AF=94=E8=B5=9B=E7=BB=93?= =?UTF-8?q?=E6=9D=9F=E5=90=8E=E5=9B=9E=E9=80=80=E6=8F=90=E4=BA=A4=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E8=A2=AB=E9=9D=99=E9=BB=98=E4=B8=A2=E5=BC=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 回退路径本身可以解析出真实题号,问题在 POST 之后:内层 fetch 只把响应 console.log 掉,从不判断成功与否,随后外层无条件覆盖成"提交失败"。日志里 那次回退实际收到的是 XMOJ 的提交冷却页(`请勿重复提交`,HUSTOJ 的 $OJ_SUBMIT_COOLDOWN_TIME 默认 5 秒,XMOJ 渲染成页面而非 302),响应被丢掉, 所以状态里没有任何提交记录。 - 把回退逻辑抽成 SubmitToEndedContestProblem,返回 {Success, Message} - 只把 redirected 当成功信号,成功后 return,不再被外层覆盖 - 遇到 `请勿重复提交` 等冷却过去后重试(3 秒一次,最多 5 次) - 其余失败从响应的 .jumbotron 取服务端原文,不再显示通用报错 - 遇到 `验证码错误` 立即刷新验证码并停止重试(答案已被消耗) - 题号改用 /\d+/ 提取,原 substring(2, 6) 会把 5 位题号截成 4 位 - 补齐缺失的 GetCaptchaParameter(),并在解析失败时恢复提交按钮 Closes #1017 Co-Authored-By: Claude Opus 5 --- XMOJ.user.js | 168 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 103 insertions(+), 65 deletions(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index 37322f82..cb9f331c 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -4473,6 +4473,102 @@ async function main() { RefreshCaptcha(""); } + const ShowSubmitStatus = (Message) => { + ErrorElement.style.display = "block"; + ErrorMessage.style.color = "red"; + try { _xmoj_disposeErrorMessageEditors(); } catch (e) { + console.error(e); + if (UtilityEnabled("DebugMode")) { + SmartAlert("XMOJ-Script internal error!\n\n" + e + "\n\n" + "If you see this message, please report it to the developer.\nDon't forget to include console logs and a way to reproduce the error!\n\nDon't want to see this message? Disable DebugMode."); + } + } + ErrorMessage.innerText = Message; + console.log(Message); + }; + + // Credit: https://github.com/boomzero/quicksubmit/blob/main/index.ts + // Also licensed under GPL-3.0 + // The contest is over, so submit.php refuses the cid+pid submission. Look up the + // real problem number on the contest page and submit to that problem instead. + // Returns {Success, Message}; Success means a submission record was created. + async function SubmitToEndedContestProblem(Source, O2Switch, ReportStatus) { + const ContestID = new URL(location.href).searchParams.get("cid"); + const ProblemNumber = new URL(location.href).searchParams.get("pid"); + const ContestResponse = await fetch("https://www.xmoj.tech/contest.php?cid=" + ContestID); + const ContestPage = await ContestResponse.text(); + if (ContestResponse.status !== 200 || ContestPage.indexOf("比赛尚未开始或私有,不能查看题目。") !== -1) { + console.error("Failed to get contest page!"); + return {Success: false, Message: "无法读取比赛页面,未能找到原题题号!"}; + } + let RealPID = undefined; + try { + const ContestDocument = new DOMParser().parseFromString(ContestPage, "text/html"); + const ProblemTable = ContestDocument.querySelector("#problemset > tbody"); + if (ProblemTable === null) { + console.error("Failed to find the problem list of the contest!"); + return {Success: false, Message: "无法解析比赛题目列表,未能找到原题题号!"}; + } + const ContestProblems = []; + for (let i = 0; i < ProblemTable.rows.length; i++) { + // The 题号 cell is padded with newlines and tabs; a fixed substring(2, 6) + // truncates any problem number that is not exactly four digits. + const ProblemNumberMatch = ProblemTable.rows[i].children[1].textContent.match(/\d+/); + ContestProblems.push(ProblemNumberMatch === null ? "" : ProblemNumberMatch[0]); + } + RealPID = ContestProblems[ProblemNumber]; + if (UtilityEnabled("DebugMode")) { + console.log("Contest Problems:", ContestProblems); + console.log("Real PID:", RealPID); + } + } catch (e) { + console.error(e); + return {Success: false, Message: "无法解析比赛题目列表,未能找到原题题号!"}; + } + if (RealPID === undefined || RealPID === "") { + return {Success: false, Message: "无法确定原题题号,请手动前往原题提交!"}; + } + // XMOJ rejects anything submitted within a few seconds of the previous submission + // with 请勿重复提交, so wait the cooldown out instead of silently dropping the code. + for (let Attempt = 0; Attempt < 5; Attempt++) { + ReportStatus("比赛已结束, 正在尝试向题目 " + RealPID + " 提交"); + const SubmitResponse = await fetch("https://www.xmoj.tech/submit.php", { + "headers": { + "content-type": "application/x-www-form-urlencoded" + }, + "referrer": location.href, + "method": "POST", + "body": "id=" + RealPID + "&language=1&" + "source=" + encodeURIComponent(Source) + O2Switch + GetCaptchaParameter() + }); + if (SubmitResponse.redirected) { + location.href = SubmitResponse.url; + return {Success: true, Message: ""}; + } + const SubmitPage = await SubmitResponse.text(); + if (UtilityEnabled("DebugMode")) { + console.log("Direct submission response:", SubmitPage); + } + // Retrying cannot help here: the answer that was sent has already been spent. + if (SubmitPage.indexOf("验证码错误") !== -1) { + await RefreshCaptcha(""); + document.querySelector("#vcode").focus(); + return {Success: false, Message: "验证码错误!请填写上方的验证码后重新提交。"}; + } + if (SubmitPage.indexOf("请勿重复提交") === -1) { + let ServerMessage = ""; + try { + const MessageElement = new DOMParser().parseFromString(SubmitPage, "text/html").querySelector(".jumbotron"); + if (MessageElement !== null) ServerMessage = MessageElement.textContent.trim(); + } catch (e) { + console.error(e); + } + return {Success: false, Message: "向题目 " + RealPID + " 提交失败!" + (ServerMessage === "" ? "请关闭脚本后重试!" : ServerMessage)}; + } + ReportStatus("提交过于频繁, 3 秒后重新尝试向题目 " + RealPID + " 提交"); + await new Promise((Resolve) => setTimeout(Resolve, 3000)); + } + return {Success: false, Message: "向题目 " + RealPID + " 提交失败!提交过于频繁,请稍后手动重试!"}; + } + PassCheck.addEventListener("click", async () => { // This is the request that actually reaches submit.php, so the captcha is checked // here as well as in the 提交 handler above. @@ -4515,76 +4611,18 @@ async function main() { document.querySelector("#vcode").focus(); return; } - if (text.indexOf("没有这个比赛!") !== -1 && new URL(location.href).searchParams.get("pid") !== null) { - // Credit: https://github.com/boomzero/quicksubmit/blob/main/index.ts - // Also licensed under GPL-3.0 - const contestReq = await fetch("https://www.xmoj.tech/contest.php?cid=" + new URL(location.href).searchParams.get("cid")); - const res = await contestReq.text(); - if ( - contestReq.status !== 200 || - res.indexOf("比赛尚未开始或私有,不能查看题目。") !== -1 - ) { - console.error(`Failed to get contest page!`); - return; - } - const parser = new DOMParser(); - const dom = parser.parseFromString(res, "text/html"); - const contestProblems = []; - const rows = (dom.querySelector( - "#problemset > tbody", - )).rows; - for (let i = 0; i < rows.length; i++) { - contestProblems.push( - rows[i].children[1].textContent.substring(2, 6).replaceAll( - "\t", - "", - ), - ); - } - rPID = contestProblems[new URL(location.href).searchParams.get("pid")]; - if (UtilityEnabled("DebugMode")) { - console.log("Contest Problems:", contestProblems); - console.log("Real PID:", rPID); - } - ErrorElement.style.display = "block"; - ErrorMessage.style.color = "red"; - try { _xmoj_disposeErrorMessageEditors(); } catch (e) { - console.error(e); - if (UtilityEnabled("DebugMode")) { - SmartAlert("XMOJ-Script internal error!\n\n" + e + "\n\n" + "If you see this message, please report it to the developer.\nDon't forget to include console logs and a way to reproduce the error!\n\nDon't want to see this message? Disable DebugMode."); - } - } - ErrorMessage.innerText = "比赛已结束, 正在尝试向题目 " + rPID + " 提交"; - console.log("比赛已结束, 正在尝试向题目 " + rPID + " 提交"); - let o2Switch = "&enable_O2=on"; - if (!document.querySelector("#enable_O2").checked) o2Switch = ""; - await fetch("https://www.xmoj.tech/submit.php", { - "headers": { - "content-type": "application/x-www-form-urlencoded" - }, - "referrer": location.href, - "method": "POST", - "body": "id=" + rPID + "&language=1&" + "source=" + encodeURIComponent(CodeMirrorElement.getValue()) + o2Switch + GetCaptchaParameter() - }).then(async (Response) => { - if (Response.redirected) { - location.href = Response.url; - } - console.log(await Response.text()); - }); - - } if (UtilityEnabled("DebugMode")) { console.log("Submission failed! Response:", text); } - ErrorElement.style.display = "block"; - ErrorMessage.style.color = "red"; - try { _xmoj_disposeErrorMessageEditors(); } catch (e) { - console.error(e); - if (UtilityEnabled("DebugMode")) { - SmartAlert("XMOJ-Script internal error!\n\n" + e + "\n\n" + "If you see this message, please report it to the developer.\nDon't forget to include console logs and a way to reproduce the error!\n\nDon't want to see this message? Disable DebugMode."); + let FailMessage = "提交失败!请关闭脚本后重试!"; + if (text.indexOf("没有这个比赛!") !== -1 && SearchParams.get("pid") !== null) { + const FallbackResult = await SubmitToEndedContestProblem(CodeMirrorElement.getValue(), o2Switch, ShowSubmitStatus); + if (FallbackResult.Success) { + return; } + FailMessage = FallbackResult.Message; } - ErrorMessage.innerText = "提交失败!请关闭脚本后重试!"; + ShowSubmitStatus(FailMessage); Submit.disabled = false; Submit.value = "提交"; } From e32a469e83c64165ef9f157f051826003b0aee12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:24:36 +0000 Subject: [PATCH 02/59] 3.6.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8537fedb..c50f9fb0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmoj-script", - "version": "3.6.4", + "version": "3.6.5", "description": "an improvement script for xmoj.tech", "main": "AddonScript.js", "scripts": { From af887e02f0f8576133846c7f39b0865dc9063288 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:24:42 +0000 Subject: [PATCH 03/59] Update version info to 3.6.5 --- Update.json | 11 +++++++++++ XMOJ.user.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Update.json b/Update.json index c9667873..1690bebb 100644 --- a/Update.json +++ b/Update.json @@ -3727,6 +3727,17 @@ } ], "Notes": "### 修复提交界面不显示验证码\n\n评测队列繁忙时 XMOJ 会启用图片验证码,但提交界面是脚本自行渲染的,服务端的验证码字段被丢弃,导致提交静默失败。现在提交界面会显示验证码图片与输入框(点击图片可更换),并在提交时携带验证码。\n\n另新增 `AutoCaptcha` 开关(默认开启):在浏览器本地用模板匹配识别 4 位数字验证码,不联网、不调用任何 AI 服务。把握不大时会留空由您填写,不会填错。" + }, + "3.6.5": { + "UpdateDate": 1789777477231, + "Prerelease": true, + "UpdateContents": [ + { + "PR": 1021, + "Description": "fix: 比赛结束后回退提交不再被静默丢弃" + } + ], + "Notes": "修复比赛结束后自动向原题提交的回退功能。此前回退提交的响应被丢弃,遇到提交冷却时会静默失败并显示\"提交失败\",状态页里也没有任何提交记录。" } } } \ No newline at end of file diff --git a/XMOJ.user.js b/XMOJ.user.js index cb9f331c..1e73d749 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name XMOJ -// @version 3.6.4 +// @version 3.6.5 // @description XMOJ增强脚本 // @author @XMOJ-Script-dev, @langningchen and the community // @namespace https://github/langningchen From ab272eed614320bbba146059f970eb6a7c105f5f Mon Sep 17 00:00:00 2001 From: boomzero Date: Sat, 19 Sep 2026 08:28:50 +0800 Subject: [PATCH 04/59] =?UTF-8?q?fix:=20=E5=9B=9E=E9=80=80=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E6=AF=8F=E6=AC=A1=E9=87=8D=E8=AF=95=E5=89=8D=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E6=A3=80=E6=9F=A5=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 冷却等待期间验证码输入框和刷新按钮仍可交互。如果用户在这 3 秒里清空了 输入框或刷新了图片,下一次重试会用空的 GetCaptchaParameter() 发出请求, 而空答案会让服务端把本 session 的 4 位验证码换成 8 位。 在循环每次 POST 之前调用 CaptchaIsMissing()(它自己会提示并恢复按钮), 并用 Handled 标志让外层直接返回,不覆盖它设置的提示。 Co-Authored-By: Claude Opus 5 --- XMOJ.user.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index 1e73d749..e8fbf499 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -4530,6 +4530,11 @@ async function main() { // XMOJ rejects anything submitted within a few seconds of the previous submission // with 请勿重复提交, so wait the cooldown out instead of silently dropping the code. for (let Attempt = 0; Attempt < 5; Attempt++) { + // The captcha field stays editable while we fetch contest.php and while we wait + // out a cooldown, so re-check it before every POST rather than trusting the + // check the 提交 handler did. Sending a blank answer would burn the session. + // CaptchaIsMissing() already shows its own message and restores the button. + if (CaptchaIsMissing()) return {Success: false, Handled: true, Message: ""}; ReportStatus("比赛已结束, 正在尝试向题目 " + RealPID + " 提交"); const SubmitResponse = await fetch("https://www.xmoj.tech/submit.php", { "headers": { @@ -4617,7 +4622,7 @@ async function main() { let FailMessage = "提交失败!请关闭脚本后重试!"; if (text.indexOf("没有这个比赛!") !== -1 && SearchParams.get("pid") !== null) { const FallbackResult = await SubmitToEndedContestProblem(CodeMirrorElement.getValue(), o2Switch, ShowSubmitStatus); - if (FallbackResult.Success) { + if (FallbackResult.Success || FallbackResult.Handled) { return; } FailMessage = FallbackResult.Message; From ad0eb05e6fd30a53fa5ef969069b1ada72e600f0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:29:55 +0000 Subject: [PATCH 05/59] Update time and description of 3.6.5 --- Update.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Update.json b/Update.json index 1690bebb..48b78ebd 100644 --- a/Update.json +++ b/Update.json @@ -3729,7 +3729,7 @@ "Notes": "### 修复提交界面不显示验证码\n\n评测队列繁忙时 XMOJ 会启用图片验证码,但提交界面是脚本自行渲染的,服务端的验证码字段被丢弃,导致提交静默失败。现在提交界面会显示验证码图片与输入框(点击图片可更换),并在提交时携带验证码。\n\n另新增 `AutoCaptcha` 开关(默认开启):在浏览器本地用模板匹配识别 4 位数字验证码,不联网、不调用任何 AI 服务。把握不大时会留空由您填写,不会填错。" }, "3.6.5": { - "UpdateDate": 1789777477231, + "UpdateDate": 1789777790191, "Prerelease": true, "UpdateContents": [ { From 157e9b2f444eaee4fd17327139f8f24c6f153a18 Mon Sep 17 00:00:00 2001 From: boomzero Date: Sat, 19 Sep 2026 08:32:59 +0800 Subject: [PATCH 06/59] =?UTF-8?q?fix:=20=E5=9B=9E=E9=80=80=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E7=9A=84=E7=BD=91=E7=BB=9C=E8=AF=B7=E6=B1=82=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E4=B8=8D=E5=86=8D=E8=AE=A9=E6=8F=90=E4=BA=A4=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E5=8D=A1=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit contest.php 或 submit.php 的 fetch 被 reject(网络错误)时,异常会一路穿出 SubmitToEndedContestProblem、穿出 .then 回调、穿出 PassCheck 的 async 监听器 ——整条链上没有任何 catch。结果 ShowSubmitStatus 和恢复按钮的两行都不会执行, 提交按钮永远停在"正在提交...",而错误框在监听器开头已经被设成 display: none, 用户什么提示都看不到。这正是本 PR 声称要修掉的那个症状。 把两处网络请求都包进 try/catch,失败时返回错误信息交给外层显示。 Co-Authored-By: Claude Opus 5 --- XMOJ.user.js | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index e8fbf499..1f59a730 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -4494,8 +4494,17 @@ async function main() { async function SubmitToEndedContestProblem(Source, O2Switch, ReportStatus) { const ContestID = new URL(location.href).searchParams.get("cid"); const ProblemNumber = new URL(location.href).searchParams.get("pid"); - const ContestResponse = await fetch("https://www.xmoj.tech/contest.php?cid=" + ContestID); - const ContestPage = await ContestResponse.text(); + // A rejected fetch here would unwind all the way out of the click handler, which + // has no catch, leaving 提交 stuck on 正在提交... with the error box still hidden. + let ContestResponse = undefined; + let ContestPage = ""; + try { + ContestResponse = await fetch("https://www.xmoj.tech/contest.php?cid=" + ContestID); + ContestPage = await ContestResponse.text(); + } catch (e) { + console.error(e); + return {Success: false, Message: "无法读取比赛页面,未能找到原题题号!"}; + } if (ContestResponse.status !== 200 || ContestPage.indexOf("比赛尚未开始或私有,不能查看题目。") !== -1) { console.error("Failed to get contest page!"); return {Success: false, Message: "无法读取比赛页面,未能找到原题题号!"}; @@ -4536,19 +4545,25 @@ async function main() { // CaptchaIsMissing() already shows its own message and restores the button. if (CaptchaIsMissing()) return {Success: false, Handled: true, Message: ""}; ReportStatus("比赛已结束, 正在尝试向题目 " + RealPID + " 提交"); - const SubmitResponse = await fetch("https://www.xmoj.tech/submit.php", { - "headers": { - "content-type": "application/x-www-form-urlencoded" - }, - "referrer": location.href, - "method": "POST", - "body": "id=" + RealPID + "&language=1&" + "source=" + encodeURIComponent(Source) + O2Switch + GetCaptchaParameter() - }); - if (SubmitResponse.redirected) { - location.href = SubmitResponse.url; - return {Success: true, Message: ""}; + let SubmitPage = ""; + try { + const SubmitResponse = await fetch("https://www.xmoj.tech/submit.php", { + "headers": { + "content-type": "application/x-www-form-urlencoded" + }, + "referrer": location.href, + "method": "POST", + "body": "id=" + RealPID + "&language=1&" + "source=" + encodeURIComponent(Source) + O2Switch + GetCaptchaParameter() + }); + if (SubmitResponse.redirected) { + location.href = SubmitResponse.url; + return {Success: true, Message: ""}; + } + SubmitPage = await SubmitResponse.text(); + } catch (e) { + console.error(e); + return {Success: false, Message: "向题目 " + RealPID + " 提交失败!网络错误,请稍后重试!"}; } - const SubmitPage = await SubmitResponse.text(); if (UtilityEnabled("DebugMode")) { console.log("Direct submission response:", SubmitPage); } From 514bd86044c7c140f3028a08d80aa95319220350 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:33:35 +0000 Subject: [PATCH 07/59] Update time and description of 3.6.5 --- Update.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Update.json b/Update.json index 48b78ebd..942f091a 100644 --- a/Update.json +++ b/Update.json @@ -3729,7 +3729,7 @@ "Notes": "### 修复提交界面不显示验证码\n\n评测队列繁忙时 XMOJ 会启用图片验证码,但提交界面是脚本自行渲染的,服务端的验证码字段被丢弃,导致提交静默失败。现在提交界面会显示验证码图片与输入框(点击图片可更换),并在提交时携带验证码。\n\n另新增 `AutoCaptcha` 开关(默认开启):在浏览器本地用模板匹配识别 4 位数字验证码,不联网、不调用任何 AI 服务。把握不大时会留空由您填写,不会填错。" }, "3.6.5": { - "UpdateDate": 1789777790191, + "UpdateDate": 1789778010947, "Prerelease": true, "UpdateContents": [ { From ba08aac5b19f2ae394137a43c1dbc9de1c26e38e Mon Sep 17 00:00:00 2001 From: boomzero Date: Sat, 19 Sep 2026 08:52:32 +0800 Subject: [PATCH 08/59] =?UTF-8?q?feat:=20=E9=AA=8C=E8=AF=81=E7=A0=81?= =?UTF-8?q?=E8=AF=86=E5=88=AB=E4=B8=8D=E5=87=BA=E6=97=B6=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=8D=A2=E4=B8=80=E5=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 --- XMOJ.user.js | 79 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index 1f59a730..da150b80 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -576,6 +576,8 @@ const CaptchaGlyphs = { // generated and 40 live captchas, 4 is the point where every wrong answer turns into a decline: it // still fills in about three quarters of them and never once guessed wrong. const CaptchaMinMargin = 4; +// With about three quarters of challenges read, five images leave well under a 1% chance of giving up. +const CaptchaMaxAttempts = 5; // Settings that start off rather than on. Both UtilityEnabled and the settings list seed missing // values, so they have to agree or whichever runs first decides the default. const DefaultOffSettings = ["DebugMode", "SuperDebug", "ReplaceXM"]; @@ -4395,40 +4397,51 @@ async function main() { document.querySelector("#CaptchaElement").style.display = "block"; CaptchaInput.value = ""; SetCaptchaStatus(StatusMessage || ""); - let ImageBlob; - try { - const CaptchaResponse = await fetch("https://www.xmoj.tech/vcode.php?" + Math.random(), {cache: "no-store"}); - ImageBlob = await CaptchaResponse.blob(); - } catch (e) { - console.error(e); - SetCaptchaStatus("验证码加载失败,请点击图片重试"); - return; - } - if (RequestID !== CaptchaRequestID) return; - if (CaptchaObjectURL !== null) URL.revokeObjectURL(CaptchaObjectURL); - CaptchaObjectURL = URL.createObjectURL(ImageBlob); - document.querySelector("#CaptchaImage").src = CaptchaObjectURL; - if (!UtilityEnabled("AutoCaptcha")) return; - let CaptchaLength = 4; - try { - CaptchaLength = await GetCaptchaLength(ImageBlob); - } catch (e) { - console.error(e); - } - if (CaptchaLength !== 4) { - SetCaptchaStatus("本次为 " + CaptchaLength + " 位字母验证码,请手动输入"); - return; - } - const Answer = await SolveCaptcha(ImageBlob); - if (RequestID !== CaptchaRequestID) return; - if (Answer === null) { - SetCaptchaStatus("这张看不太准,请手动输入,或点击图片换一张"); - return; + // Only a submitted answer counts against the session, so fetching another image is + // free: when the solver declines one it is cheaper to ask for a fresh challenge than + // to make the user type it. Each fetch replaces the answer the session expects, so + // this stops as soon as the user starts typing against the image on screen. + for (let Attempt = 1; Attempt <= CaptchaMaxAttempts; Attempt++) { + if (Attempt > 1) { + await new Promise((Resolve) => setTimeout(Resolve, 300)); + if (RequestID !== CaptchaRequestID || CaptchaInput.value !== "") return; + SetCaptchaStatus("这张看不太准,正在自动换一张(" + Attempt + "/" + CaptchaMaxAttempts + ")"); + } + let ImageBlob; + try { + const CaptchaResponse = await fetch("https://www.xmoj.tech/vcode.php?" + Math.random(), {cache: "no-store"}); + ImageBlob = await CaptchaResponse.blob(); + } catch (e) { + console.error(e); + if (RequestID === CaptchaRequestID) SetCaptchaStatus("验证码加载失败,请点击图片重试"); + return; + } + if (RequestID !== CaptchaRequestID) return; + if (CaptchaObjectURL !== null) URL.revokeObjectURL(CaptchaObjectURL); + CaptchaObjectURL = URL.createObjectURL(ImageBlob); + document.querySelector("#CaptchaImage").src = CaptchaObjectURL; + if (!UtilityEnabled("AutoCaptcha")) return; + let CaptchaLength = 4; + try { + CaptchaLength = await GetCaptchaLength(ImageBlob); + } catch (e) { + console.error(e); + } + if (CaptchaLength !== 4) { + SetCaptchaStatus("本次为 " + CaptchaLength + " 位字母验证码,请手动输入"); + return; + } + const Answer = await SolveCaptcha(ImageBlob); + if (RequestID !== CaptchaRequestID) return; + // Never overwrite what the user has already started typing. + if (CaptchaInput.value !== "") return; + if (Answer !== null) { + CaptchaInput.value = Answer; + SetCaptchaStatus("已自动识别,若与图片不符请手动修改"); + return; + } } - // Never overwrite what the user has already started typing. - if (CaptchaInput.value !== "") return; - CaptchaInput.value = Answer; - SetCaptchaStatus("已自动识别,若与图片不符请手动修改"); + SetCaptchaStatus("连续几张都看不太准,请手动输入,或点击图片换一张"); }; document.querySelector("#CaptchaImage").addEventListener("click", () => { RefreshCaptcha(""); From c2b21da5057743e167929384ef7223bad8fdc813 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:52:58 +0000 Subject: [PATCH 09/59] 3.6.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c50f9fb0..e6af0b78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmoj-script", - "version": "3.6.5", + "version": "3.6.6", "description": "an improvement script for xmoj.tech", "main": "AddonScript.js", "scripts": { From 05e1956415377c48a066bafbb0edb5c3384f1837 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:53:04 +0000 Subject: [PATCH 10/59] Update version info to 3.6.6 --- Update.json | 11 +++++++++++ XMOJ.user.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Update.json b/Update.json index 942f091a..f6875e83 100644 --- a/Update.json +++ b/Update.json @@ -3738,6 +3738,17 @@ } ], "Notes": "修复比赛结束后自动向原题提交的回退功能。此前回退提交的响应被丢弃,遇到提交冷却时会静默失败并显示\"提交失败\",状态页里也没有任何提交记录。" + }, + "3.6.6": { + "UpdateDate": 1789779179257, + "Prerelease": true, + "UpdateContents": [ + { + "PR": 1023, + "Description": "feat: 验证码识别不出时自动换一张" + } + ], + "Notes": "自动识别验证码时,若当前这张看不准,脚本会自动换一张重试(最多 5 张),无需手动点击图片。" } } } \ No newline at end of file diff --git a/XMOJ.user.js b/XMOJ.user.js index da150b80..6ec9bc7c 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name XMOJ -// @version 3.6.5 +// @version 3.6.6 // @description XMOJ增强脚本 // @author @XMOJ-Script-dev, @langningchen and the community // @namespace https://github/langningchen From 2544311ca83a25484727b86a472b7e5db77106dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:55:01 +0000 Subject: [PATCH 11/59] Update time and description of 3.6.6 --- Update.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Update.json b/Update.json index f6875e83..f85af226 100644 --- a/Update.json +++ b/Update.json @@ -3740,7 +3740,7 @@ "Notes": "修复比赛结束后自动向原题提交的回退功能。此前回退提交的响应被丢弃,遇到提交冷却时会静默失败并显示\"提交失败\",状态页里也没有任何提交记录。" }, "3.6.6": { - "UpdateDate": 1789779179257, + "UpdateDate": 1789779296094, "Prerelease": true, "UpdateContents": [ { From 62e9c7f142fc2088b1136e0ab48b81c800dffc0d Mon Sep 17 00:00:00 2001 From: boomzero Date: Sat, 19 Sep 2026 08:55:17 +0800 Subject: [PATCH 12/59] =?UTF-8?q?fix:=20=E6=8D=A2=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E6=9C=9F=E9=97=B4=E9=94=81=E5=AE=9A=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E6=A1=86=EF=BC=8C=E9=81=BF=E5=85=8D=E6=8C=89=E6=97=A7=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=A1=AB=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 --- XMOJ.user.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index 6ec9bc7c..2f74ae62 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -4400,26 +4400,36 @@ async function main() { // Only a submitted answer counts against the session, so fetching another image is // free: when the solver declines one it is cheaper to ask for a fresh challenge than // to make the user type it. Each fetch replaces the answer the session expects, so - // this stops as soon as the user starts typing against the image on screen. + // this stops if the user starts typing against the image on screen before the next one. for (let Attempt = 1; Attempt <= CaptchaMaxAttempts; Attempt++) { if (Attempt > 1) { await new Promise((Resolve) => setTimeout(Resolve, 300)); if (RequestID !== CaptchaRequestID || CaptchaInput.value !== "") return; SetCaptchaStatus("这张看不太准,正在自动换一张(" + Attempt + "/" + CaptchaMaxAttempts + ")"); } + // From the moment vcode.php is requested the image on screen no longer matches the + // session, so anything typed from it would be a guaranteed wrong answer. The box is + // locked until the new image replaces it. A newer call that takes over leaves the + // lock to be released by that call rather than by this one. + CaptchaInput.readOnly = true; let ImageBlob; try { const CaptchaResponse = await fetch("https://www.xmoj.tech/vcode.php?" + Math.random(), {cache: "no-store"}); ImageBlob = await CaptchaResponse.blob(); } catch (e) { console.error(e); - if (RequestID === CaptchaRequestID) SetCaptchaStatus("验证码加载失败,请点击图片重试"); + if (RequestID === CaptchaRequestID) { + CaptchaInput.readOnly = false; + SetCaptchaStatus("验证码加载失败,请点击图片重试"); + } return; } if (RequestID !== CaptchaRequestID) return; if (CaptchaObjectURL !== null) URL.revokeObjectURL(CaptchaObjectURL); CaptchaObjectURL = URL.createObjectURL(ImageBlob); document.querySelector("#CaptchaImage").src = CaptchaObjectURL; + CaptchaInput.value = ""; + CaptchaInput.readOnly = false; if (!UtilityEnabled("AutoCaptcha")) return; let CaptchaLength = 4; try { From abff30484f56188c5c0c767c518a99dcb4d53984 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 00:55:54 +0000 Subject: [PATCH 13/59] Update time and description of 3.6.6 --- Update.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Update.json b/Update.json index f85af226..37752240 100644 --- a/Update.json +++ b/Update.json @@ -3740,7 +3740,7 @@ "Notes": "修复比赛结束后自动向原题提交的回退功能。此前回退提交的响应被丢弃,遇到提交冷却时会静默失败并显示\"提交失败\",状态页里也没有任何提交记录。" }, "3.6.6": { - "UpdateDate": 1789779296094, + "UpdateDate": 1789779349314, "Prerelease": true, "UpdateContents": [ { From c6856529ae730c4ba117e082c4b41914d40cac88 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 01:07:44 +0000 Subject: [PATCH 14/59] 3.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e6af0b78..454e50c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xmoj-script", - "version": "3.6.6", + "version": "3.7.0", "description": "an improvement script for xmoj.tech", "main": "AddonScript.js", "scripts": { From 6085c4e6b61e00ab8292193e91308e431bd2cd84 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 19 Sep 2026 01:07:46 +0000 Subject: [PATCH 15/59] Update to release 3.7.0 --- Update.json | 31 +++++++++++++++++++++++++++++++ XMOJ.user.js | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Update.json b/Update.json index 37752240..3bc3bf70 100644 --- a/Update.json +++ b/Update.json @@ -3749,6 +3749,37 @@ } ], "Notes": "自动识别验证码时,若当前这张看不准,脚本会自动换一张重试(最多 5 张),无需手动点击图片。" + }, + "3.7.0": { + "UpdateDate": 1789780064668, + "Prerelease": false, + "UpdateContents": [ + { + "PR": 1006, + "Description": "Fix #1004" + }, + { + "PR": 1013, + "Description": "fix: handle PID 0 submission rows" + }, + { + "PR": 1015, + "Description": "feat: compress ApplyData payloads with gzip and Base93" + }, + { + "PR": 1019, + "Description": "fix: 在提交界面显示并提交验证码" + }, + { + "PR": 1021, + "Description": "fix: 比赛结束后回退提交不再被静默丢弃" + }, + { + "PR": 1023, + "Description": "feat: 验证码识别不出时自动换一张" + } + ], + "Notes": "

3.7.0 — 自上一正式版 3.6.0 以来的完整更新

\n

本次正式版整合 3.6.1、3.6.2、3.6.3、3.6.4、3.6.5 和 3.6.6 的全部功能更新与修复。

\n

3.6.1:代码对比显示修复(#1006,修复 #1004)

\n
  • 修复 Monaco 代码对比区域的高度布局,为合并编辑器容器设置高度,恢复对比内容的正常显示。
\n

3.6.2:提交记录布局修复(#1013)

\n
  • 修复题目 ID 为 0、缺少重新提交链接时提交记录的排版错误,避免相关处理打断页面。
  • 安全构造提交记录中的链接,并将缺失链接的判断限定在需要重新提交链接的处理逻辑中。
\n

3.6.3:获取数据功能升级(#1015)

\n
    \n
  • 页面没有数据申请区域时自动创建获取数据控件。
  • \n
  • 默认模式采用 gzip + Base93 压缩传输,逐字节保留任意输入,支持文本、Unicode 和混合内容;无效 UTF-8 以可逆的逐字节转义形式显示。
  • \n
  • 新增可选 NSC3 高速数值模式,压缩 long long 整数及每行数值个数;规范数值输入可恢复空格、空行、换行与末尾换行,非规范或混合内容原样回退。
  • \n
  • 新增“保留换行”选项,默认开启。关闭后,规范数值输入恢复为单行空格分隔数据,降低随机行长带来的输出开销;仅适用于 cin 或 scanf 等不依赖行边界的读取方式,不适用于 getline 或按行解析。
  • \n
  • 界面增加各模式的说明与适用范围,帮助选择通用模式或高速数值模式。
  • \n
  • 生成的数据获取程序先向 stderr 输出并刷新,再通过 abort() 触发运行错误以返回数据;同时兼容读取旧版异常包装结果。
  • \n
\n

3.6.4:提交验证码支持(#1019)

\n
    \n
  • 修复评测队列繁忙、服务端启用验证码时,脚本提交界面丢失验证码字段而导致提交失败的问题。
  • \n
  • 显示验证码图片与输入框,支持点击图片更换、按回车提交,并在提交请求中携带验证码。
  • \n
  • 新增 AutoCaptcha 设置,支持在浏览器本地通过模板匹配识别四位数字验证码,不调用外部 AI 服务。识别不确定时交由用户输入;非四位数字类型提示手动填写。
  • \n
  • 普通提交与强制提交均检查验证码是否为空,并在实际发送请求前再次检查,避免用户中途清空或刷新图片后仍发送空验证码。
  • \n
  • 若服务端在页面加载后才要求验证码,或返回验证码错误,显示并刷新验证码、恢复提交按钮并提示重新填写。
  • \n
\n

3.6.5:比赛结束后回退提交修复(#1021)

\n
    \n
  • 修复比赛结束后向原题回退提交时响应被忽略、提交静默丢失的问题。
  • \n
  • 从比赛题目列表中解析完整原题编号,避免固定截取四位数字造成题号错误。
  • \n
  • 正确处理成功跳转、提交冷却与服务端错误;遇到重复提交限制时按三秒间隔重试,最多尝试五次,并显示进度及失败原因。
  • \n
  • 每次回退请求前重新检查验证码并携带当前输入;验证码失效时刷新图片并要求重新填写。
  • \n
  • 处理比赛页面读取、题目列表解析及提交网络错误,恢复按钮状态,避免一直停留在“正在提交”。
  • \n
\n

3.6.6:验证码自动更换与重试(#1023)

\n
    \n
  • 启用自动识别后,若当前验证码识别不确定,自动更换图片重试,最多尝试五张;仍不确定时提示手动输入或点击换图。
  • \n
  • 换图请求期间暂时锁定输入框,避免用户根据旧图片填写;图片加载完成或请求失败后恢复输入。
  • \n
  • 防止过期异步请求覆盖较新的验证码状态,并避免自动识别覆盖用户已经输入的内容。
  • \n
  • 验证码图片加载失败时给出明确提示,支持点击图片重试。
  • \n
" } } } \ No newline at end of file diff --git a/XMOJ.user.js b/XMOJ.user.js index 2f74ae62..494f9a4e 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -1,6 +1,6 @@ // ==UserScript== // @name XMOJ -// @version 3.6.6 +// @version 3.7.0 // @description XMOJ增强脚本 // @author @XMOJ-Script-dev, @langningchen and the community // @namespace https://github/langningchen From 0303ba78d8190809903db2a1612a81bac8432340 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 09:22:41 +0000 Subject: [PATCH 16/59] =?UTF-8?q?fix:=20=E6=89=80=E6=9C=89=20querySelector?= =?UTF-8?q?=20=E8=B0=83=E7=94=A8=E5=89=8D=E5=A2=9E=E5=8A=A0=20null=20?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=20(#1009)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在每个对 querySelector 结果取属性/调用方法的地方先判断是否为 null, 避免在 403/404 等页面结构不同时抛出 TypeError。 - 语句:前面加 if (xxx.querySelector(...) != null) - 条件:在条件中加 xxx.querySelector(...) != null && - 变量声明/赋值:为 null 时使用空值([] / "" / 0) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0135Ggqqp6xktQZytLRJQ9nc --- XMOJ.user.js | 438 +++++++++++++++++++++++++-------------------------- 1 file changed, 219 insertions(+), 219 deletions(-) diff --git a/XMOJ.user.js b/XMOJ.user.js index 494f9a4e..833de08d 100644 --- a/XMOJ.user.js +++ b/XMOJ.user.js @@ -715,8 +715,8 @@ let GetUserInfo = async (Username) => { return null; } const ParsedDocument = new DOMParser().parseFromString(Response, "text/html"); - let Rating = (parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(4) > td:nth-child(2)").innerText.trim()) / parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(3) > td:nth-child(2)").innerText.trim())).toFixed(3) * 1000; - let Temp = ParsedDocument.querySelector("#statics > tbody").children; + let Rating = (ParsedDocument.querySelector("#statics > tbody > tr:nth-child(4) > td:nth-child(2)") != null && ParsedDocument.querySelector("#statics > tbody > tr:nth-child(3) > td:nth-child(2)") != null) ? (parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(4) > td:nth-child(2)").innerText.trim()) / parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(3) > td:nth-child(2)").innerText.trim())).toFixed(3) * 1000 : 0; + let Temp = (ParsedDocument.querySelector("#statics > tbody") != null) ? ParsedDocument.querySelector("#statics > tbody").children : []; let Email = Temp[Temp.length - 1].children[1].innerText.trim(); let EmailHash = CryptoJS.MD5(Email).toString(); localStorage.setItem("UserScript-User-" + Username + "-UserRating", Rating); @@ -2043,7 +2043,7 @@ let IsAdmin = AdminUserList.indexOf(CurrentUsername) !== -1; const prefersDark = window.matchMedia("(prefers-color-scheme: dark)"); const applyTheme = (theme) => { - document.querySelector("html").setAttribute("data-bs-theme", theme); + if (document.querySelector("html") != null) document.querySelector("html").setAttribute("data-bs-theme", theme); localStorage.setItem("UserScript-Setting-DarkMode", theme === "dark" ? "true" : "false"); }; const applySystemTheme = (e) => applyTheme(e.matches ? "dark" : "light"); @@ -2307,11 +2307,11 @@ async function main() { let Discussion = null; if (UtilityEnabled("Discussion")) { Discussion = document.createElement("li"); - document.querySelector("#navbar > ul:nth-child(1)").appendChild(Discussion); + if (document.querySelector("#navbar > ul:nth-child(1)") != null) document.querySelector("#navbar > ul:nth-child(1)").appendChild(Discussion); Discussion.innerHTML = "讨论"; } if (UtilityEnabled("Translate")) { - document.querySelector("#navbar > ul:nth-child(1) > li:nth-child(2) > a").innerText = "题库"; + if (document.querySelector("#navbar > ul:nth-child(1) > li:nth-child(2) > a") != null) document.querySelector("#navbar > ul:nth-child(1) > li:nth-child(2) > a").innerText = "题库"; } //send analytics RequestAPI("SendData", {}); @@ -2407,13 +2407,13 @@ async function main() { } else { loadResources(); } - document.querySelector("nav").className = "navbar navbar-expand-lg bg-body-tertiary"; - document.querySelector("#navbar > ul:nth-child(1)").classList = "navbar-nav me-auto mb-2 mb-lg-0"; - document.querySelector("body > div > nav > div > div.navbar-header").outerHTML = `${UtilityEnabled("ReplaceXM") ? "高老师" : "小明"}的OJ`; - document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li").classList = "nav-item dropdown"; - document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a").className = "nav-link dropdown-toggle"; - document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a > span.caret").remove(); - Temp = document.querySelector("#navbar > ul:nth-child(1)").children; + if (document.querySelector("nav") != null) document.querySelector("nav").className = "navbar navbar-expand-lg bg-body-tertiary"; + if (document.querySelector("#navbar > ul:nth-child(1)") != null) document.querySelector("#navbar > ul:nth-child(1)").classList = "navbar-nav me-auto mb-2 mb-lg-0"; + if (document.querySelector("body > div > nav > div > div.navbar-header") != null) document.querySelector("body > div > nav > div > div.navbar-header").outerHTML = `${UtilityEnabled("ReplaceXM") ? "高老师" : "小明"}的OJ`; + if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li") != null) document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li").classList = "nav-item dropdown"; + if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a") != null) document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a").className = "nav-link dropdown-toggle"; + if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a > span.caret") != null) document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a > span.caret").remove(); + Temp = (document.querySelector("#navbar > ul:nth-child(1)") != null) ? document.querySelector("#navbar > ul:nth-child(1)").children : []; for (var i = 0; i < Temp.length; i++) { if (Temp[i].classList.contains("active")) { Temp[i].classList.remove("active"); @@ -2422,8 +2422,8 @@ async function main() { Temp[i].classList.add("nav-item"); Temp[i].children[0].classList.add("nav-link"); } - document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a").setAttribute("data-bs-toggle", "dropdown"); - document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a").removeAttribute("data-toggle"); + if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a") != null) document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a").setAttribute("data-bs-toggle", "dropdown"); + if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a") != null) document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > a").removeAttribute("data-toggle"); } if (UtilityEnabled("RemoveUseless") && document.getElementsByTagName("marquee")[0] != undefined) { document.getElementsByTagName("marquee")[0].remove(); @@ -2504,7 +2504,7 @@ async function main() { hideDropdownItems(); } }); - } else if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > ul") != undefined && document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > ul > li:nth-child(2)").innerText != "个人中心") { + } else if (document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > ul") != undefined && document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > ul > li:nth-child(2)") != null && document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > ul > li:nth-child(2)").innerText != "个人中心") { let PopupUL = document.querySelector("#navbar > ul.nav.navbar-nav.navbar-right > li > ul"); PopupUL.style.cursor = 'pointer'; PopupUL.innerHTML = ` @@ -2642,17 +2642,17 @@ async function main() { let spacer = document.createElement("div"); spacer.style.height = '48px'; document.body.insertBefore(spacer, document.body.firstChild); - UpdateDiv.querySelector(".btn-close").addEventListener("click", function () { + if (UpdateDiv.querySelector(".btn-close") != null) UpdateDiv.querySelector(".btn-close").addEventListener("click", function () { document.body.removeChild(spacer); }); } document.body.appendChild(UpdateDiv); - document.querySelector("body > div").insertBefore(UpdateDiv, document.querySelector("body > div > div.mt-3")); + if (document.querySelector("body > div") != null) document.querySelector("body > div").insertBefore(UpdateDiv, document.querySelector("body > div > div.mt-3")); } if (localStorage.getItem("UserScript-Update-LastVersion") != GM_info.script.version) { localStorage.setItem("UserScript-Update-LastVersion", GM_info.script.version); let UpdateDiv = document.createElement("div"); - document.querySelector("body").appendChild(UpdateDiv); + if (document.querySelector("body") != null) document.querySelector("body").appendChild(UpdateDiv); UpdateDiv.className = "modal fade"; UpdateDiv.id = "UpdateModal"; UpdateDiv.tabIndex = -1; @@ -3046,7 +3046,7 @@ async function main() { FeedbackCard.appendChild(FeedbackCardBody); Container.appendChild(FeedbackCard); } else { - let Temp = document.querySelector("body > div > div.mt-3 > div > div.col-md-8").children; + let Temp = (document.querySelector("body > div > div.mt-3 > div > div.col-md-8") != null) ? document.querySelector("body > div > div.mt-3 > div > div.col-md-8").children : []; let NewsData = []; for (let i = 0; i < Temp.length; i += 2) { let Title = Temp[i].children[0].innerText; @@ -3057,7 +3057,7 @@ async function main() { let Body = Temp[i + 1].innerHTML; NewsData.push({"Title": Title, "Time": new Date(Time), "Body": Body}); } - document.querySelector("body > div > div.mt-3 > div > div.col-md-8").innerHTML = ""; + if (document.querySelector("body > div > div.mt-3 > div > div.col-md-8") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-8").innerHTML = ""; for (let i = 0; i < NewsData.length; i++) { let NewsRow = document.createElement("div"); NewsRow.className = "cnt-row"; @@ -3072,10 +3072,10 @@ async function main() { NewsRowBody.className = "cnt-row-body"; NewsRowBody.innerHTML = NewsData[i].Body; NewsRow.appendChild(NewsRowBody); - document.querySelector("body > div > div.mt-3 > div > div.col-md-8").appendChild(NewsRow); + if (document.querySelector("body > div > div.mt-3 > div > div.col-md-8") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-8").appendChild(NewsRow); } - let CountDownData = document.querySelector("#countdown_list").innerHTML; - document.querySelector("body > div > div.mt-3 > div > div.col-md-4").innerHTML = `
+ let CountDownData = (document.querySelector("#countdown_list") != null) ? document.querySelector("#countdown_list").innerHTML : ""; + if (document.querySelector("body > div > div.mt-3 > div > div.col-md-4") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-4").innerHTML = `
倒计时
${CountDownData}
`; @@ -3083,38 +3083,38 @@ async function main() { for (let i = 0; i < Tables.length; i++) { TidyTable(Tables[i]); } - document.querySelector("body > div > div.mt-3 > div > div.col-md-4").innerHTML += `
+ if (document.querySelector("body > div > div.mt-3 > div > div.col-md-4") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-4").innerHTML += `
公告
加载中...
`; RequestAPI("GetNotice", {}, (Response) => { if (Response.Success) { - document.querySelector("body > div.container > div > div > div.col-md-4 > div:nth-child(2) > div.cnt-row-body").innerHTML = marked.parse(Response.Data["Notice"]).replaceAll(/@([a-zA-Z0-9]+)/g, `@$1`); + if (document.querySelector("body > div.container > div > div > div.col-md-4 > div:nth-child(2) > div.cnt-row-body") != null) document.querySelector("body > div.container > div > div > div.col-md-4 > div:nth-child(2) > div.cnt-row-body").innerHTML = marked.parse(Response.Data["Notice"]).replaceAll(/@([a-zA-Z0-9]+)/g, `@$1`); RenderMathJax(); let UsernameElements = document.getElementsByClassName("Usernames"); for (let i = 0; i < UsernameElements.length; i++) { GetUsernameHTML(UsernameElements[i], UsernameElements[i].innerText, true); } } else { - document.querySelector("body > div.container > div > div > div.col-md-4 > div:nth-child(2) > div.cnt-row-body").innerHTML = "加载失败: " + Response.Message; + if (document.querySelector("body > div.container > div > div > div.col-md-4 > div:nth-child(2) > div.cnt-row-body") != null) document.querySelector("body > div.container > div > div > div.col-md-4 > div:nth-child(2) > div.cnt-row-body").innerHTML = "加载失败: " + Response.Message; } }); } } else if (location.pathname == "/problemset.php") { if (UtilityEnabled("Translate")) { - document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > input").placeholder = "题目编号"; - document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > button").innerText = "确认"; - document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(3) > form > input").placeholder = "标题或内容"; - document.querySelector("#problemset > thead > tr > th:nth-child(1)").innerText = "状态"; + if (document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > input") != null) document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > input").placeholder = "题目编号"; + if (document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > button") != null) document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > button").innerText = "确认"; + if (document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(3) > form > input") != null) document.querySelector("body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(3) > form > input").placeholder = "标题或内容"; + if (document.querySelector("#problemset > thead > tr > th:nth-child(1)") != null) document.querySelector("#problemset > thead > tr > th:nth-child(1)").innerText = "状态"; } if (UtilityEnabled("ResetType")) { - document.querySelector("#problemset > thead > tr > th:nth-child(1)").style.width = "5%"; - document.querySelector("#problemset > thead > tr > th:nth-child(2)").style.width = "10%"; - document.querySelector("#problemset > thead > tr > th:nth-child(3)").style.width = "75%"; - document.querySelector("#problemset > thead > tr > th:nth-child(4)").style.width = "5%"; - document.querySelector("#problemset > thead > tr > th:nth-child(5)").style.width = "5%"; + if (document.querySelector("#problemset > thead > tr > th:nth-child(1)") != null) document.querySelector("#problemset > thead > tr > th:nth-child(1)").style.width = "5%"; + if (document.querySelector("#problemset > thead > tr > th:nth-child(2)") != null) document.querySelector("#problemset > thead > tr > th:nth-child(2)").style.width = "10%"; + if (document.querySelector("#problemset > thead > tr > th:nth-child(3)") != null) document.querySelector("#problemset > thead > tr > th:nth-child(3)").style.width = "75%"; + if (document.querySelector("#problemset > thead > tr > th:nth-child(4)") != null) document.querySelector("#problemset > thead > tr > th:nth-child(4)").style.width = "5%"; + if (document.querySelector("#problemset > thead > tr > th:nth-child(5)") != null) document.querySelector("#problemset > thead > tr > th:nth-child(5)").style.width = "5%"; } - document.querySelector("body > div > div.mt-3 > center > table:nth-child(2)").outerHTML = ` + if (document.querySelector("body > div > div.mt-3 > center > table:nth-child(2)") != null) document.querySelector("body > div > div.mt-3 > center > table:nth-child(2)").outerHTML = `
@@ -3131,10 +3131,10 @@ async function main() {
`; if (SearchParams.get("search") != null) { - document.querySelector("body > div > div.mt-3 > center > div > div:nth-child(3) > form > input").value = SearchParams.get("search"); + if (document.querySelector("body > div > div.mt-3 > center > div > div:nth-child(3) > form > input") != null) document.querySelector("body > div > div.mt-3 > center > div > div:nth-child(3) > form > input").value = SearchParams.get("search"); } - let Temp = document.querySelector("#problemset").rows; + let Temp = (document.querySelector("#problemset") != null) ? document.querySelector("#problemset").rows : []; for (let i = 1; i < Temp.length; i++) { localStorage.setItem("UserScript-Problem-" + Temp[i].children[1].innerText + "-Name", Temp[i].children[2].innerText); } @@ -3182,7 +3182,7 @@ async function main() { problemSwitcher.style.transform = "translateY(-50%)"; problemSwitcher.style.maxHeight = "80vh"; problemSwitcher.style.overflowY = "auto"; - if (document.querySelector("html").getAttribute("data-bs-theme") == "dark") { + if (document.querySelector("html") != null && document.querySelector("html").getAttribute("data-bs-theme") == "dark") { problemSwitcher.style.backgroundColor = UtilityEnabled("MonochromeUI") ? "#000" : "rgba(0, 0, 0, 0.8)"; } else { problemSwitcher.style.backgroundColor = UtilityEnabled("MonochromeUI") ? "#FFF" : "rgba(255, 255, 255, 0.8)"; @@ -3211,13 +3211,13 @@ async function main() { document.body.appendChild(problemSwitcher); } if (document.querySelector("body > div > div.mt-3 > h2") != null) { - document.querySelector("body > div > div.mt-3").innerHTML = "没有此题目或题目对你不可见"; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = "没有此题目或题目对你不可见"; setTimeout(() => { location.href = "https://www.xmoj.tech/problemset.php"; }, 1000); } else { let PID = localStorage.getItem("UserScript-Contest-" + SearchParams.get("cid") + "-Problem-" + SearchParams.get("pid") + "-PID"); - if (document.querySelector("body > div > div.mt-3 > center").lastElementChild !== null) { + if (document.querySelector("body > div > div.mt-3 > center") != null && document.querySelector("body > div > div.mt-3 > center").lastElementChild !== null) { document.querySelector("body > div > div.mt-3 > center").lastElementChild.style.marginLeft = "10px"; } //修复提交按钮 @@ -3236,10 +3236,10 @@ async function main() { // Replace the element with the button SubmitLink.parentNode.replaceChild(SubmitButton, SubmitLink); // Remove the button's outer [] - let str = document.querySelector('.mt-3 > center:nth-child(1)').innerHTML; + let str = (document.querySelector('.mt-3 > center:nth-child(1)') != null) ? document.querySelector('.mt-3 > center:nth-child(1)').innerHTML : ""; let target = SubmitButton.outerHTML; - document.querySelector('.mt-3 > center:nth-child(1)').innerHTML = str.replace(new RegExp(`(.?)${target}(.?)`, 'g'), target); - document.querySelector('html body.placeholder-glow div.container div.mt-3 center button#SubmitButton.btn.btn-outline-secondary').onclick = function () { + if (document.querySelector('.mt-3 > center:nth-child(1)') != null) document.querySelector('.mt-3 > center:nth-child(1)').innerHTML = str.replace(new RegExp(`(.?)${target}(.?)`, 'g'), target); + if (document.querySelector('html body.placeholder-glow div.container div.mt-3 center button#SubmitButton.btn.btn-outline-secondary') != null) document.querySelector('html body.placeholder-glow div.container div.mt-3 center button#SubmitButton.btn.btn-outline-secondary').onclick = function () { window.location.href = SubmitLink.href; console.log(SubmitLink.href); }; @@ -3248,7 +3248,7 @@ async function main() { Temp[i].parentElement.className = "card"; } if (UtilityEnabled("RemoveUseless")) { - document.querySelector("h2.lang_en").remove(); + if (document.querySelector("h2.lang_en") != null) document.querySelector("h2.lang_en").remove(); document.getElementsByTagName("center")[1].remove(); } if (UtilityEnabled("CopySamples")) { @@ -3277,7 +3277,7 @@ async function main() { } IOFileElement.parentNode.insertBefore(document.createElement("br"), IOFileElement); IOFileElement.remove(); - let Temp = document.querySelector("body > div > div.mt-3 > center").childNodes[2].data.trim(); + let Temp = (document.querySelector("body > div > div.mt-3 > center") != null) ? document.querySelector("body > div > div.mt-3 > center").childNodes[2].data.trim() : ""; let IOFilename = Temp.substring(0, Temp.length - 3); localStorage.setItem("UserScript-Problem-" + PID + "-IOFilename", IOFilename); } @@ -3322,7 +3322,7 @@ async function main() { open("https://www.xmoj.tech/discuss3/discuss.php?pid=" + SearchParams.get("id"), "_blank"); } }); - document.querySelector("body > div > div.mt-3 > center").appendChild(DiscussButton); + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").appendChild(DiscussButton); let UnreadBadge = document.createElement("span"); UnreadBadge.className = "position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger"; UnreadBadge.style.display = "none"; @@ -3391,7 +3391,7 @@ async function main() { } else if (location.pathname == "/status.php") { if (SearchParams.get("ByUserScript") == null) { document.title = "提交状态"; - document.querySelector("body > script:nth-child(5)").remove(); + if (document.querySelector("body > script:nth-child(5)") != null) document.querySelector("body > script:nth-child(5)").remove(); if (UtilityEnabled("NewBootstrap")) { var checkNum = function(str) { var patrn = /^[0-9]{1,20}$/; @@ -3407,7 +3407,7 @@ async function main() { let CurrentJresultParam = params.get("jresult"); let CurrentJresult = checkNum(CurrentJresultParam) && -1 <= CurrentJresultParam && CurrentJresultParam <= 11 ? Number(CurrentJresultParam) : "-1"; - document.querySelector("#simform").outerHTML = `
+ if (document.querySelector("#simform") != null) document.querySelector("#simform").outerHTML = `
@@ -3453,7 +3453,7 @@ async function main() { if (UtilityEnabled("ImproveACRate")) { let ImproveACRateButton = document.createElement("button"); - document.querySelector("body > div.container > div > div.input-append").appendChild(ImproveACRateButton); + if (document.querySelector("body > div.container > div > div.input-append") != null) document.querySelector("body > div.container > div > div.input-append").appendChild(ImproveACRateButton); ImproveACRateButton.className = "btn btn-outline-secondary"; ImproveACRateButton.innerText = "提高正确率"; ImproveACRateButton.disabled = true; @@ -3463,8 +3463,8 @@ async function main() { return Response.text(); }).then((Response) => { let ParsedDocument = new DOMParser().parseFromString(Response, "text/html"); - ImproveACRateButton.innerText += "(" + (parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(4) > td:nth-child(2)").innerText) / parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(3) > td:nth-child(2)").innerText) * 100).toFixed(2) + "%)"; - let Temp = ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script").innerText.split("\n")[5].split(";"); + if (ParsedDocument.querySelector("#statics > tbody > tr:nth-child(4) > td:nth-child(2)") != null && ParsedDocument.querySelector("#statics > tbody > tr:nth-child(3) > td:nth-child(2)") != null) ImproveACRateButton.innerText += "(" + (parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(4) > td:nth-child(2)").innerText) / parseInt(ParsedDocument.querySelector("#statics > tbody > tr:nth-child(3) > td:nth-child(2)").innerText) * 100).toFixed(2) + "%)"; + let Temp = (ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script") != null) ? ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script").innerText.split("\n")[5].split(";") : []; for (let i = 0; i < Temp.length; i++) { ACProblems.push(Number(Temp[i].substring(2, Temp[i].indexOf(",")))); } @@ -3488,7 +3488,7 @@ async function main() { return Result.text(); }).then((Result) => { let ParsedDocument = new DOMParser().parseFromString(Result, "text/html"); - SID = ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText; + if (ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)") != null) SID = ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText; }); let Code = ""; await fetch("https://www.xmoj.tech/getsource.php?id=" + SID) @@ -3513,7 +3513,7 @@ async function main() { } if (UtilityEnabled("CompareSource")) { let CompareButton = document.createElement("button"); - document.querySelector("body > div.container > div > div.input-append").appendChild(CompareButton); + if (document.querySelector("body > div.container > div > div.input-append") != null) document.querySelector("body > div.container > div > div.input-append").appendChild(CompareButton); CompareButton.className = "btn btn-outline-secondary"; CompareButton.innerText = "比较提交记录"; CompareButton.addEventListener("click", () => { @@ -3522,11 +3522,11 @@ async function main() { CompareButton.style.marginBottom = "7px"; } if (UtilityEnabled("ResetType")) { - document.querySelector("#result-tab > thead > tr > th:nth-child(1)").remove(); - document.querySelector("#result-tab > thead > tr > th:nth-child(2)").remove(); - document.querySelector("#result-tab > thead > tr > th:nth-child(10)").innerHTML = "开启O2"; + if (document.querySelector("#result-tab > thead > tr > th:nth-child(1)") != null) document.querySelector("#result-tab > thead > tr > th:nth-child(1)").remove(); + if (document.querySelector("#result-tab > thead > tr > th:nth-child(2)") != null) document.querySelector("#result-tab > thead > tr > th:nth-child(2)").remove(); + if (document.querySelector("#result-tab > thead > tr > th:nth-child(10)") != null) document.querySelector("#result-tab > thead > tr > th:nth-child(10)").innerHTML = "开启O2"; } - let Temp = document.querySelector("#result-tab > tbody").childNodes; + let Temp = (document.querySelector("#result-tab > tbody") != null) ? document.querySelector("#result-tab > tbody").childNodes : []; let SolutionIDs = []; for (let i = 1; i < Temp.length; i += 2) { let SID = Number(Temp[i].childNodes[1].innerText); @@ -3661,10 +3661,10 @@ async function main() { } if (location.href.indexOf("?cid=") == -1) { if (UtilityEnabled("ResetType")) { - document.querySelector("body > div > div.mt-3 > center").innerHTML = String(document.querySelector("body > div > div.mt-3 > center").innerHTML).replaceAll("ServerTime:", "服务器时间:"); - document.querySelector("body > div > div.mt-3 > center > table").style.marginTop = "10px"; + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").innerHTML = String(document.querySelector("body > div > div.mt-3 > center").innerHTML).replaceAll("ServerTime:", "服务器时间:"); + if (document.querySelector("body > div > div.mt-3 > center > table") != null) document.querySelector("body > div > div.mt-3 > center > table").style.marginTop = "10px"; - document.querySelector("body > div > div.mt-3 > center > form").outerHTML = `
+ if (document.querySelector("body > div > div.mt-3 > center > form") != null) document.querySelector("body > div > div.mt-3 > center > form").outerHTML = `
@@ -3675,13 +3675,13 @@ async function main() {
`; } if (UtilityEnabled("Translate")) { - document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[0].innerText = "编号"; - document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[1].innerText = "标题"; - document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[2].innerText = "状态"; - document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[3].remove(); - document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[3].innerText = "创建者"; + if (document.querySelector("body > div > div.mt-3 > center > table > thead > tr") != null) document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[0].innerText = "编号"; + if (document.querySelector("body > div > div.mt-3 > center > table > thead > tr") != null) document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[1].innerText = "标题"; + if (document.querySelector("body > div > div.mt-3 > center > table > thead > tr") != null) document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[2].innerText = "状态"; + if (document.querySelector("body > div > div.mt-3 > center > table > thead > tr") != null) document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[3].remove(); + if (document.querySelector("body > div > div.mt-3 > center > table > thead > tr") != null) document.querySelector("body > div > div.mt-3 > center > table > thead > tr").childNodes[3].innerText = "创建者"; } - let Temp = document.querySelector("body > div > div.mt-3 > center > table > tbody").childNodes; + let Temp = (document.querySelector("body > div > div.mt-3 > center > table > tbody") != null) ? document.querySelector("body > div > div.mt-3 > center > table > tbody").childNodes : []; for (let i = 1; i < Temp.length; i++) { let CurrentElement = Temp[i].childNodes[2].childNodes; if (CurrentElement[1].childNodes[0].data.indexOf("运行中") != -1) { @@ -3713,24 +3713,24 @@ async function main() { } else { document.getElementsByTagName("h3")[0].innerHTML = "比赛" + document.getElementsByTagName("h3")[0].innerHTML.substring(7); if (document.querySelector("#time_left") != null) { - let EndTime = document.querySelector("body > div > div.mt-3 > center").childNodes[3].data; + let EndTime = (document.querySelector("body > div > div.mt-3 > center") != null) ? document.querySelector("body > div > div.mt-3 > center").childNodes[3].data : ""; EndTime = EndTime.substring(EndTime.indexOf("结束时间是:") + 6, EndTime.lastIndexOf("。")); EndTime = new Date(EndTime).getTime(); if (new Date().getTime() < EndTime) { - document.querySelector("#time_left").classList.add("UpdateByJS"); - document.querySelector("#time_left").setAttribute("EndTime", EndTime); + if (document.querySelector("#time_left") != null) document.querySelector("#time_left").classList.add("UpdateByJS"); + if (document.querySelector("#time_left") != null) document.querySelector("#time_left").setAttribute("EndTime", EndTime); } } - let HTMLData = document.querySelector("body > div > div.mt-3 > center > div").innerHTML; + let HTMLData = (document.querySelector("body > div > div.mt-3 > center > div") != null) ? document.querySelector("body > div > div.mt-3 > center > div").innerHTML : ""; HTMLData = HTMLData.replaceAll("  \n  ", " ") HTMLData = HTMLData.replaceAll("
开始于: ", "开始时间:") HTMLData = HTMLData.replaceAll("\n结束于: ", "
结束时间:") HTMLData = HTMLData.replaceAll("\n订正截止日期: ", "
订正截止日期:") HTMLData = HTMLData.replaceAll("\n现在时间: ", "当前时间:") HTMLData = HTMLData.replaceAll("\n状态:", "
状态:") - document.querySelector("body > div > div.mt-3 > center > div").innerHTML = HTMLData; - if (UtilityEnabled("RemoveAlerts") && document.querySelector("body > div > div.mt-3 > center").innerHTML.indexOf("尚未开始比赛") != -1) { - document.querySelector("body > div > div.mt-3 > center > a").setAttribute("href", "start_contest.php?cid=" + SearchParams.get("cid")); + if (document.querySelector("body > div > div.mt-3 > center > div") != null) document.querySelector("body > div > div.mt-3 > center > div").innerHTML = HTMLData; + if (UtilityEnabled("RemoveAlerts") && document.querySelector("body > div > div.mt-3 > center") != null && document.querySelector("body > div > div.mt-3 > center").innerHTML.indexOf("尚未开始比赛") != -1) { + if (document.querySelector("body > div > div.mt-3 > center > a") != null) document.querySelector("body > div > div.mt-3 > center > a").setAttribute("href", "start_contest.php?cid=" + SearchParams.get("cid")); } else if (UtilityEnabled("AutoRefresh")) { addEventListener("focus", async () => { await fetch(location.href) @@ -3739,35 +3739,35 @@ async function main() { }) .then((Response) => { let ParsedDocument = new DOMParser().parseFromString(Response, "text/html"); - let Temp = ParsedDocument.querySelector("#problemset > tbody").children; + let Temp = (ParsedDocument.querySelector("#problemset > tbody") != null) ? ParsedDocument.querySelector("#problemset > tbody").children : []; if (UtilityEnabled("ReplaceYN")) { for (let i = 0; i < Temp.length; i++) { let Status = Temp[i].children[0].innerText; if (Status.indexOf("Y") != -1) { - document.querySelector("#problemset > tbody").children[i].children[0].children[0].className = "status status_y"; - document.querySelector("#problemset > tbody").children[i].children[0].children[0].innerText = "✓"; + if (document.querySelector("#problemset > tbody") != null) document.querySelector("#problemset > tbody").children[i].children[0].children[0].className = "status status_y"; + if (document.querySelector("#problemset > tbody") != null) document.querySelector("#problemset > tbody").children[i].children[0].children[0].innerText = "✓"; } else if (Status.indexOf("N") != -1) { - document.querySelector("#problemset > tbody").children[i].children[0].children[0].className = "status status_n"; - document.querySelector("#problemset > tbody").children[i].children[0].children[0].innerText = "✗"; + if (document.querySelector("#problemset > tbody") != null) document.querySelector("#problemset > tbody").children[i].children[0].children[0].className = "status status_n"; + if (document.querySelector("#problemset > tbody") != null) document.querySelector("#problemset > tbody").children[i].children[0].children[0].innerText = "✗"; } } } }); }); - document.querySelector("body > div > div.mt-3 > center > br:nth-child(2)").remove(); - document.querySelector("body > div > div.mt-3 > center > br:nth-child(2)").remove(); - document.querySelector("body > div > div.mt-3 > center > div > .red").innerHTML = String(document.querySelector("body > div > div.mt-3 > center > div > .red").innerHTML).replaceAll("
", "

"); + if (document.querySelector("body > div > div.mt-3 > center > br:nth-child(2)") != null) document.querySelector("body > div > div.mt-3 > center > br:nth-child(2)").remove(); + if (document.querySelector("body > div > div.mt-3 > center > br:nth-child(2)") != null) document.querySelector("body > div > div.mt-3 > center > br:nth-child(2)").remove(); + if (document.querySelector("body > div > div.mt-3 > center > div > .red") != null) document.querySelector("body > div > div.mt-3 > center > div > .red").innerHTML = String(document.querySelector("body > div > div.mt-3 > center > div > .red").innerHTML).replaceAll("
", "

"); - document.querySelector("#problemset > tbody").innerHTML = String(document.querySelector("#problemset > tbody").innerHTML).replaceAll(/\t ([0-9]*)      问题  ([^<]*)/g, "$2. $1"); + if (document.querySelector("#problemset > tbody") != null) document.querySelector("#problemset > tbody").innerHTML = String(document.querySelector("#problemset > tbody").innerHTML).replaceAll(/\t ([0-9]*)      问题  ([^<]*)/g, "$2. $1"); - document.querySelector("#problemset > tbody").innerHTML = String(document.querySelector("#problemset > tbody").innerHTML).replaceAll(/\t\*([0-9]*)      问题  ([^<]*)/g, "拓展$2. $1"); + if (document.querySelector("#problemset > tbody") != null) document.querySelector("#problemset > tbody").innerHTML = String(document.querySelector("#problemset > tbody").innerHTML).replaceAll(/\t\*([0-9]*)      问题  ([^<]*)/g, "拓展$2. $1"); - if (UtilityEnabled("MoreSTD") && document.querySelector("#problemset > thead > tr").innerHTML.indexOf("标程") != -1) { + if (UtilityEnabled("MoreSTD") && document.querySelector("#problemset > thead > tr") != null && document.querySelector("#problemset > thead > tr").innerHTML.indexOf("标程") != -1) { let Temp = document.querySelector("#problemset > thead > tr").children; for (let i = 0; i < Temp.length; i++) { if (Temp[i].innerText == "标程") { Temp[i].remove(); - let Temp2 = document.querySelector("#problemset > tbody").children; + let Temp2 = (document.querySelector("#problemset > tbody") != null) ? document.querySelector("#problemset > tbody").children : []; for (let j = 0; j < Temp2.length; j++) { if (Temp2[j].children[i] != undefined) { Temp2[j].children[i].remove(); @@ -3775,14 +3775,14 @@ async function main() { } } } - document.querySelector("#problemset > thead > tr").innerHTML += "标程"; - Temp = document.querySelector("#problemset > tbody").children; + if (document.querySelector("#problemset > thead > tr") != null) document.querySelector("#problemset > thead > tr").innerHTML += "标程"; + Temp = (document.querySelector("#problemset > tbody") != null) ? document.querySelector("#problemset > tbody").children : []; for (let i = 0; i < Temp.length; i++) { Temp[i].innerHTML += "
打开"; } } - Temp = document.querySelector("#problemset > tbody").rows; + Temp = (document.querySelector("#problemset > tbody") != null) ? document.querySelector("#problemset > tbody").rows : []; for (let i = 0; i < Temp.length; i++) { if (Temp[i].childNodes[0].children.length == 0) { Temp[i].childNodes[0].innerHTML = "
"; @@ -3798,7 +3798,7 @@ async function main() { let CheatDiv = document.createElement("div"); CheatDiv.style.marginTop = "20px"; CheatDiv.style.textAlign = "left"; - document.querySelector("body > div > div.mt-3 > center").insertBefore(CheatDiv, document.querySelector("#problemset")); + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").insertBefore(CheatDiv, document.querySelector("#problemset")); if (UtilityEnabled("AutoCheat")) { let AutoCheatButton = document.createElement("button"); CheatDiv.appendChild(AutoCheatButton); @@ -3814,13 +3814,13 @@ async function main() { return Response.text(); }).then((Response) => { let ParsedDocument = new DOMParser().parseFromString(Response, "text/html"); - let Temp = ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script").innerText.split("\n")[5].split(";"); + let Temp = (ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script") != null) ? ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script").innerText.split("\n")[5].split(";") : []; for (let i = 0; i < Temp.length; i++) { ACProblems.push(Number(Temp[i].substring(2, Temp[i].indexOf(",")))); } AutoCheatButton.disabled = false; }); - let Rows = document.querySelector("#problemset > tbody").rows; + let Rows = (document.querySelector("#problemset > tbody") != null) ? document.querySelector("#problemset > tbody").rows : []; for (let i = 0; i < Rows.length; i++) { ContestProblems.push(Rows[i].children[1].innerText.substring(Rows[i].children[1].innerText.indexOf('.') + 2)).toFixed; } @@ -3846,7 +3846,7 @@ async function main() { return Result.text(); }).then((Result) => { let ParsedDocument = new DOMParser().parseFromString(Result, "text/html"); - SID = ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText; + if (ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)") != null) SID = ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText; }); await new Promise(r => setTimeout(r, 500)); let Code = ""; @@ -3887,7 +3887,7 @@ async function main() { OpenAllButton.style.marginRight = "5px"; CheatDiv.appendChild(OpenAllButton); OpenAllButton.addEventListener("click", () => { - let Rows = document.querySelector("#problemset > tbody").rows; + let Rows = (document.querySelector("#problemset > tbody") != null) ? document.querySelector("#problemset > tbody").rows : []; for (let i = 0; i < Rows.length; i++) { open(Rows[i].children[2].children[0].href, "_blank"); } @@ -3897,7 +3897,7 @@ async function main() { OpenUnsolvedButton.innerText = "打开未解决题目"; CheatDiv.appendChild(OpenUnsolvedButton); OpenUnsolvedButton.addEventListener("click", () => { - let Rows = document.querySelector("#problemset > tbody").rows; + let Rows = (document.querySelector("#problemset > tbody") != null) ? document.querySelector("#problemset > tbody").rows : []; for (let i = 0; i < Rows.length; i++) { if (!Rows[i].children[0].children[0].classList.contains("status_y")) { open(Rows[i].children[2].children[0].href, "_blank"); @@ -3905,18 +3905,18 @@ async function main() { } }); } - localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemCount", document.querySelector("#problemset > tbody").rows.length); + if (document.querySelector("#problemset > tbody") != null) localStorage.setItem("UserScript-Contest-" + SearchParams.get("cid") + "-ProblemCount", document.querySelector("#problemset > tbody").rows.length); } } } else if (location.pathname == "/contestrank-oi.php") { if (document.querySelector("#rank") == null) { - document.querySelector("body > div > div.mt-3").innerHTML = "

比赛排名

"; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = "

比赛排名

"; } if (SearchParams.get("ByUserScript") == null) { - if (document.querySelector("body > div > div.mt-3 > center > h3").innerText == "比赛排名") { - document.querySelector("#rank").innerText = "比赛暂时还没有排名"; + if (document.querySelector("body > div > div.mt-3 > center > h3") != null && document.querySelector("body > div > div.mt-3 > center > h3").innerText == "比赛排名") { + if (document.querySelector("#rank") != null) document.querySelector("#rank").innerText = "比赛暂时还没有排名"; } else { - document.querySelector("body > div > div.mt-3 > center > h3").innerText = document.querySelector("body > div > div.mt-3 > center > h3").innerText.substring(document.querySelector("body > div > div.mt-3 > center > h3").innerText.indexOf(" -- ") + 4) + "(OI排名)"; + if (document.querySelector("body > div > div.mt-3 > center > h3") != null) document.querySelector("body > div > div.mt-3 > center > h3").innerText = document.querySelector("body > div > div.mt-3 > center > h3").innerText.substring(document.querySelector("body > div > div.mt-3 > center > h3").innerText.indexOf(" -- ") + 4) + "(OI排名)"; let HeaderCells = document.querySelectorAll("#rank > thead > tr > *"); HeaderCells[0].innerText = "排名"; HeaderCells[1].innerText = "用户"; @@ -3997,11 +3997,11 @@ async function main() { Temp[i].cells[j].style.color = (UtilityEnabled("DarkMode") ? "white" : "black"); } } - document.querySelector("#rank > tbody").innerHTML = ParsedDocument.querySelector("#rank > tbody").innerHTML; + if (document.querySelector("#rank > tbody") != null && ParsedDocument.querySelector("#rank > tbody") != null) document.querySelector("#rank > tbody").innerHTML = ParsedDocument.querySelector("#rank > tbody").innerHTML; }); }; RefreshOIRank(); - document.title = document.querySelector("body > div.container > div > center > h3").innerText; + if (document.querySelector("body > div.container > div > center > h3") != null) document.title = document.querySelector("body > div.container > div > center > h3").innerText; if (UtilityEnabled("AutoRefresh")) { addEventListener("focus", RefreshOIRank); } @@ -4010,19 +4010,19 @@ async function main() { Style.innerHTML += "td {"; Style.innerHTML += " white-space: nowrap;"; Style.innerHTML += "}"; - document.querySelector("body > div.container > div > center").style.paddingBottom = "10px"; - document.querySelector("body > div.container > div > center > a").style.display = "none"; - document.title = document.querySelector("body > div.container > div > center > h3").innerText; + if (document.querySelector("body > div.container > div > center") != null) document.querySelector("body > div.container > div > center").style.paddingBottom = "10px"; + if (document.querySelector("body > div.container > div > center > a") != null) document.querySelector("body > div.container > div > center > a").style.display = "none"; + if (document.querySelector("body > div.container > div > center > h3") != null) document.title = document.querySelector("body > div.container > div > center > h3").innerText; } else if (location.pathname == "/contestrank-correct.php") { if (document.querySelector("#rank") == null) { - document.querySelector("body > div > div.mt-3").innerHTML = "

比赛排名

"; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = "

比赛排名

"; } - if (document.querySelector("body > div > div.mt-3 > center > h3").innerText == "比赛排名") { - document.querySelector("#rank").innerText = "比赛暂时还没有排名"; + if (document.querySelector("body > div > div.mt-3 > center > h3") != null && document.querySelector("body > div > div.mt-3 > center > h3").innerText == "比赛排名") { + if (document.querySelector("#rank") != null) document.querySelector("#rank").innerText = "比赛暂时还没有排名"; } else { if (UtilityEnabled("ResetType")) { - document.querySelector("body > div > div.mt-3 > center > h3").innerText = document.querySelector("body > div > div.mt-3 > center > h3").innerText.substring(document.querySelector("body > div > div.mt-3 > center > h3").innerText.indexOf(" -- ") + 4) + "(订正排名)"; - document.querySelector("body > div > div.mt-3 > center > a").remove(); + if (document.querySelector("body > div > div.mt-3 > center > h3") != null) document.querySelector("body > div > div.mt-3 > center > h3").innerText = document.querySelector("body > div > div.mt-3 > center > h3").innerText.substring(document.querySelector("body > div > div.mt-3 > center > h3").innerText.indexOf(" -- ") + 4) + "(订正排名)"; + if (document.querySelector("body > div > div.mt-3 > center > a") != null) document.querySelector("body > div > div.mt-3 > center > a").remove(); } let HeaderCells = document.querySelectorAll("#rank > thead > tr > *"); HeaderCells[0].innerText = "排名"; @@ -4104,11 +4104,11 @@ async function main() { Temp[i].cells[j].style.color = (UtilityEnabled("DarkMode") ? "white" : "black"); } } - document.querySelector("#rank > tbody").innerHTML = ParsedDocument.querySelector("#rank > tbody").innerHTML; + if (document.querySelector("#rank > tbody") != null && ParsedDocument.querySelector("#rank > tbody") != null) document.querySelector("#rank > tbody").innerHTML = ParsedDocument.querySelector("#rank > tbody").innerHTML; }); }; RefreshCorrectRank(); - document.title = document.querySelector("body > div.container > div > center > h3").innerText; + if (document.querySelector("body > div.container > div > center > h3") != null) document.title = document.querySelector("body > div.container > div > center > h3").innerText; if (UtilityEnabled("AutoRefresh")) { addEventListener("focus", RefreshCorrectRank); } @@ -4122,7 +4122,7 @@ async function main() { const NativeCaptchaShown = document.querySelector("input[name='vcode']") != null || document.querySelector("img#vcode") != null || localStorage.getItem("UserScript-ForceCaptcha") === "true"; - document.querySelector("body > div > div.mt-3").innerHTML = `
+ if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = `

Loading...

@@ -4167,7 +4167,7 @@ async function main() { } })(); if (UtilityEnabled("AutoO2")) { - document.querySelector("#enable_O2").checked = true; + if (document.querySelector("#enable_O2") != null) document.querySelector("#enable_O2").checked = true; } const getSubmitStorageKey = () => (SearchParams.get("id") != null ? ('XMOJ-Submit-id-' + SearchParams.get("id")) : ('XMOJ-Submit-cid-' + SearchParams.get("cid") + '-pid-' + SearchParams.get("pid"))); let CodeMirrorElement; @@ -4261,7 +4261,7 @@ async function main() { let CaptchaObjectURL = null; let CaptchaRequestID = 0; const SetCaptchaStatus = (Message) => { - document.querySelector("#CaptchaStatus").innerText = Message; + if (document.querySelector("#CaptchaStatus") != null) document.querySelector("#CaptchaStatus").innerText = Message; }; // Byte 6-7 of a GIF header is the little endian width. vcode.php sizes the image as // 15px per character, so 60px means the easy 4 digit challenge while a wider image is @@ -4394,7 +4394,7 @@ async function main() { const RefreshCaptcha = async (StatusMessage) => { const RequestID = ++CaptchaRequestID; const CaptchaInput = document.querySelector("#vcode"); - document.querySelector("#CaptchaElement").style.display = "block"; + if (document.querySelector("#CaptchaElement") != null) document.querySelector("#CaptchaElement").style.display = "block"; CaptchaInput.value = ""; SetCaptchaStatus(StatusMessage || ""); // Only a submitted answer counts against the session, so fetching another image is @@ -4427,7 +4427,7 @@ async function main() { if (RequestID !== CaptchaRequestID) return; if (CaptchaObjectURL !== null) URL.revokeObjectURL(CaptchaObjectURL); CaptchaObjectURL = URL.createObjectURL(ImageBlob); - document.querySelector("#CaptchaImage").src = CaptchaObjectURL; + if (document.querySelector("#CaptchaImage") != null) document.querySelector("#CaptchaImage").src = CaptchaObjectURL; CaptchaInput.value = ""; CaptchaInput.readOnly = false; if (!UtilityEnabled("AutoCaptcha")) return; @@ -4453,10 +4453,10 @@ async function main() { } SetCaptchaStatus("连续几张都看不太准,请手动输入,或点击图片换一张"); }; - document.querySelector("#CaptchaImage").addEventListener("click", () => { + if (document.querySelector("#CaptchaImage") != null) document.querySelector("#CaptchaImage").addEventListener("click", () => { RefreshCaptcha(""); }); - document.querySelector("#vcode").addEventListener("keydown", (KeyEvent) => { + if (document.querySelector("#vcode") != null) document.querySelector("#vcode").addEventListener("keydown", (KeyEvent) => { if (KeyEvent.key === "Enter") { KeyEvent.preventDefault(); Submit.click(); @@ -4466,7 +4466,7 @@ async function main() { // one costs nothing and covers the case where the queue grew past the enforcement // threshold after this page was rendered. const GetCaptchaParameter = () => { - const CaptchaValue = document.querySelector("#vcode").value.trim(); + const CaptchaValue = (document.querySelector("#vcode") != null) ? document.querySelector("#vcode").value.trim() : ""; return CaptchaValue === "" ? "" : "&vcode=" + encodeURIComponent(CaptchaValue); }; // Submitting a blank answer makes the server mark the session as having failed the @@ -4475,8 +4475,8 @@ async function main() { // 提交 is pressed: a warning leaves 强制提交 on screen, and the captcha can be cleared // in between by refreshing the image or emptying the box by hand. const CaptchaIsMissing = () => { - if (document.querySelector("#CaptchaElement").style.display === "none") return false; - if (document.querySelector("#vcode").value.trim() !== "") return false; + if (document.querySelector("#CaptchaElement") != null && document.querySelector("#CaptchaElement").style.display === "none") return false; + if (document.querySelector("#vcode") != null && document.querySelector("#vcode").value.trim() !== "") return false; PassCheck.style.display = "none"; ErrorElement.style.display = "block"; ErrorMessage.style.color = "red"; @@ -4489,7 +4489,7 @@ async function main() { ErrorMessage.innerText = "当前评测队列繁忙,请先填写上方的验证码。"; Submit.disabled = false; Submit.value = "提交"; - document.querySelector("#vcode").focus(); + if (document.querySelector("#vcode") != null) document.querySelector("#vcode").focus(); return true; }; if (NativeCaptchaShown) { @@ -4593,7 +4593,7 @@ async function main() { // Retrying cannot help here: the answer that was sent has already been spent. if (SubmitPage.indexOf("验证码错误") !== -1) { await RefreshCaptcha(""); - document.querySelector("#vcode").focus(); + if (document.querySelector("#vcode") != null) document.querySelector("#vcode").focus(); return {Success: false, Message: "验证码错误!请填写上方的验证码后重新提交。"}; } if (SubmitPage.indexOf("请勿重复提交") === -1) { @@ -4617,10 +4617,10 @@ async function main() { // here as well as in the 提交 handler above. if (CaptchaIsMissing()) return; ErrorElement.style.display = "none"; - document.querySelector("#Submit").disabled = true; - document.querySelector("#Submit").value = "正在提交..."; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").disabled = true; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").value = "正在提交..."; let o2Switch = "&enable_O2=on"; - if (!document.querySelector("#enable_O2").checked) o2Switch = ""; + if (document.querySelector("#enable_O2") != null && !document.querySelector("#enable_O2").checked) o2Switch = ""; await fetch("https://www.xmoj.tech/submit.php", { "headers": { "content-type": "application/x-www-form-urlencoded" @@ -4651,7 +4651,7 @@ async function main() { ErrorMessage.innerText = "验证码错误!请填写上方的验证码后重新提交。"; Submit.disabled = false; Submit.value = "提交"; - document.querySelector("#vcode").focus(); + if (document.querySelector("#vcode") != null) document.querySelector("#vcode").focus(); return; } if (UtilityEnabled("DebugMode")) { @@ -4675,8 +4675,8 @@ async function main() { Submit.addEventListener("click", async () => { PassCheck.style.display = "none"; ErrorElement.style.display = "none"; - document.querySelector("#Submit").disabled = true; - document.querySelector("#Submit").value = "正在检查..."; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").disabled = true; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").value = "正在检查..."; if (CaptchaIsMissing()) return; let Source = CodeMirrorElement.getValue(); let PID = 0; @@ -4754,8 +4754,8 @@ async function main() { pre.textContent = 'freopen("' + IOFilename + '.in", "r", stdin);\nfreopen("' + IOFilename + '.out", "w", stdout);'; codeHost.appendChild(pre); } - document.querySelector("#Submit").disabled = false; - document.querySelector("#Submit").value = "提交"; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").disabled = false; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").value = "提交"; return false; } else if (RegExp("//.*freopen").test(Source)) { PassCheck.style.display = ""; @@ -4768,8 +4768,8 @@ async function main() { } } ErrorMessage.innerText = "请不要注释freopen语句"; - document.querySelector("#Submit").disabled = false; - document.querySelector("#Submit").value = "提交"; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").disabled = false; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").value = "提交"; return false; } } @@ -4784,8 +4784,8 @@ async function main() { } } ErrorMessage.innerText = "源代码为空"; - document.querySelector("#Submit").disabled = false; - document.querySelector("#Submit").value = "提交"; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").disabled = false; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").value = "提交"; return false; } if (UtilityEnabled("CompileError")) { @@ -4812,8 +4812,8 @@ async function main() { } } ErrorMessage.innerText = "编译错误:\n" + Response.stderr.trim(); - document.querySelector("#Submit").disabled = false; - document.querySelector("#Submit").value = "提交"; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").disabled = false; + if (document.querySelector("#Submit") != null) document.querySelector("#Submit").value = "提交"; return false; } else { PassCheck.click(); @@ -4825,7 +4825,7 @@ async function main() { } else if (location.pathname == "/modifypage.php") { if (SearchParams.get("ByUserScript") != null) { document.title = "XMOJ-Script 更新日志"; - document.querySelector("body > div > div.mt-3").innerHTML = ""; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = ""; await fetch(ServerURL + "/Update.json", {cache: "no-cache"}) .then((Response) => { return Response.json(); @@ -4835,7 +4835,7 @@ async function main() { let Version = Object.keys(Response.UpdateHistory)[i]; let Data = Response.UpdateHistory[Version]; let UpdateDataCard = document.createElement("div"); - document.querySelector("body > div > div.mt-3").appendChild(UpdateDataCard); + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").appendChild(UpdateDataCard); UpdateDataCard.className = "card mb-3"; if (Data.Prerelease) UpdateDataCard.classList.add("text-secondary"); let UpdateDataCardBody = document.createElement("div"); @@ -4885,7 +4885,7 @@ async function main() { let AtcoderAccount = document.getElementsByName("acc_atc")[0].value; let USACOAccount = document.getElementsByName("acc_usaco")[0].value; let LuoguAccount = document.getElementsByName("acc_luogu")[0].value; - document.querySelector("body > div > div").innerHTML = `
+ if (document.querySelector("body > div > div") != null) document.querySelector("body > div > div").innerHTML = `
@@ -4988,12 +4988,12 @@ async function main() { }); ModifyInfo.addEventListener("click", async () => { ModifyInfo.disabled = true; - ModifyInfo.querySelector("span").style.display = ""; + if (ModifyInfo.querySelector("span") != null) ModifyInfo.querySelector("span").style.display = ""; ErrorElement.style.display = "none"; SuccessElement.style.display = "none"; - let BadgeContent = document.querySelector("#BadgeContent").value; - let BadgeBackgroundColor = document.querySelector("#BadgeBackgroundColor").value; - let BadgeColor = document.querySelector("#BadgeColor").value; + let BadgeContent = (document.querySelector("#BadgeContent") != null) ? document.querySelector("#BadgeContent").value : ""; + let BadgeBackgroundColor = (document.querySelector("#BadgeBackgroundColor") != null) ? document.querySelector("#BadgeBackgroundColor").value : ""; + let BadgeColor = (document.querySelector("#BadgeColor") != null) ? document.querySelector("#BadgeColor").value : ""; await new Promise((Resolve) => { RequestAPI("EditBadge", { "UserID": String(CurrentUsername), @@ -5005,22 +5005,22 @@ async function main() { Resolve(); } else { ModifyInfo.disabled = false; - ModifyInfo.querySelector("span").style.display = "none"; + if (ModifyInfo.querySelector("span") != null) ModifyInfo.querySelector("span").style.display = "none"; ErrorElement.style.display = "block"; ErrorElement.innerText = Response.Message; } }); }); - let Nickname = document.querySelector("#Nickname").value; - let OldPassword = document.querySelector("#OldPassword").value; - let NewPassword = document.querySelector("#NewPassword").value; - let NewPasswordAgain = document.querySelector("#NewPasswordAgain").value; - let School = document.querySelector("#School").value; - let EmailAddress = document.querySelector("#EmailAddress").value; - let CodeforcesAccount = document.querySelector("#CodeforcesAccount").value; - let AtcoderAccount = document.querySelector("#AtcoderAccount").value; - let USACOAccount = document.querySelector("#USACOAccount").value; - let LuoguAccount = document.querySelector("#LuoguAccount").value; + let Nickname = (document.querySelector("#Nickname") != null) ? document.querySelector("#Nickname").value : ""; + let OldPassword = (document.querySelector("#OldPassword") != null) ? document.querySelector("#OldPassword").value : ""; + let NewPassword = (document.querySelector("#NewPassword") != null) ? document.querySelector("#NewPassword").value : ""; + let NewPasswordAgain = (document.querySelector("#NewPasswordAgain") != null) ? document.querySelector("#NewPasswordAgain").value : ""; + let School = (document.querySelector("#School") != null) ? document.querySelector("#School").value : ""; + let EmailAddress = (document.querySelector("#EmailAddress") != null) ? document.querySelector("#EmailAddress").value : ""; + let CodeforcesAccount = (document.querySelector("#CodeforcesAccount") != null) ? document.querySelector("#CodeforcesAccount").value : ""; + let AtcoderAccount = (document.querySelector("#AtcoderAccount") != null) ? document.querySelector("#AtcoderAccount").value : ""; + let USACOAccount = (document.querySelector("#USACOAccount") != null) ? document.querySelector("#USACOAccount").value : ""; + let LuoguAccount = (document.querySelector("#LuoguAccount") != null) ? document.querySelector("#LuoguAccount").value : ""; await fetch("https://www.xmoj.tech/modify.php", { "headers": { "content-type": "application/x-www-form-urlencoded" @@ -5030,12 +5030,12 @@ async function main() { "body": "nick=" + encodeURIComponent(Nickname) + "&" + "opassword=" + encodeURIComponent(OldPassword) + "&" + "npassword=" + encodeURIComponent(NewPassword) + "&" + "rptpassword=" + encodeURIComponent(NewPasswordAgain) + "&" + "school=" + encodeURIComponent(School) + "&" + "email=" + encodeURIComponent(EmailAddress) + "&" + "acc_cf=" + encodeURIComponent(CodeforcesAccount) + "&" + "acc_atc=" + encodeURIComponent(AtcoderAccount) + "&" + "acc_usaco=" + encodeURIComponent(USACOAccount) + "&" + "acc_luogu=" + encodeURIComponent(LuoguAccount) }); ModifyInfo.disabled = false; - ModifyInfo.querySelector("span").style.display = "none"; + if (ModifyInfo.querySelector("span") != null) ModifyInfo.querySelector("span").style.display = "none"; SuccessElement.style.display = "block"; }); if (UtilityEnabled("ExportACCode")) { let ExportACCode = document.createElement("button"); - document.querySelector("body > div.container > div").appendChild(ExportACCode); + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").appendChild(ExportACCode); ExportACCode.innerText = "导出AC代码"; ExportACCode.className = "btn btn-outline-secondary"; ExportACCode.addEventListener("click", () => { @@ -5103,10 +5103,10 @@ async function main() { Temp[i].remove(); } } - eval(document.querySelector("body > script:nth-child(5)").innerHTML); - document.querySelector("#statics > tbody > tr:nth-child(1)").remove(); + if (document.querySelector("body > script:nth-child(5)") != null) eval(document.querySelector("body > script:nth-child(5)").innerHTML); + if (document.querySelector("#statics > tbody > tr:nth-child(1)") != null) document.querySelector("#statics > tbody > tr:nth-child(1)").remove(); - let Temp = document.querySelector("#statics > tbody").children; + let Temp = (document.querySelector("#statics > tbody") != null) ? document.querySelector("#statics > tbody").children : []; for (let i = 0; i < Temp.length; i++) { if (Temp[i].children[0] != undefined) { if (Temp[i].children[0].innerText == "Statistics") { @@ -5118,18 +5118,18 @@ async function main() { } } - Temp = document.querySelector("#statics > tbody > tr:nth-child(1) > td:nth-child(3)").childNodes; + Temp = (document.querySelector("#statics > tbody > tr:nth-child(1) > td:nth-child(3)") != null) ? document.querySelector("#statics > tbody > tr:nth-child(1) > td:nth-child(3)").childNodes : []; let ACProblems = []; for (let i = 0; i < Temp.length; i++) { if (Temp[i].tagName == "A" && Temp[i].href.indexOf("problem.php?id=") != -1) { ACProblems.push(Number(Temp[i].innerText.trim())); } } - document.querySelector("#statics > tbody > tr:nth-child(1) > td:nth-child(3)").remove(); + if (document.querySelector("#statics > tbody > tr:nth-child(1) > td:nth-child(3)") != null) document.querySelector("#statics > tbody > tr:nth-child(1) > td:nth-child(3)").remove(); let UserID, UserNick; - [UserID, UserNick] = document.querySelector("#statics > caption").childNodes[0].data.trim().split("--"); - document.querySelector("#statics > caption").remove(); + if (document.querySelector("#statics > caption") != null) [UserID, UserNick] = document.querySelector("#statics > caption").childNodes[0].data.trim().split("--"); + if (document.querySelector("#statics > caption") != null) document.querySelector("#statics > caption").remove(); document.title = "用户 " + UserID + " 的个人中心"; let Row = document.createElement("div"); Row.className = "row"; @@ -5245,11 +5245,11 @@ async function main() { for (let i = 0; i < ACProblems.length; i++) { RightDiv.innerHTML += "" + ACProblems[i] + " "; } - document.querySelector("body > div > div").innerHTML = ""; - document.querySelector("body > div > div").appendChild(Row); + if (document.querySelector("body > div > div") != null) document.querySelector("body > div > div").innerHTML = ""; + if (document.querySelector("body > div > div") != null) document.querySelector("body > div > div").appendChild(Row); } else { document.title = "上传标程"; - document.querySelector("body > div > div.mt-3").innerHTML = ` + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = `
0%
@@ -5275,7 +5275,7 @@ async function main() { return Response.text(); }).then((Response) => { let ParsedDocument = new DOMParser().parseFromString(Response, "text/html"); - let ScriptData = ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script").innerText; + let ScriptData = (ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script") != null) ? ParsedDocument.querySelector("#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script").innerText : ""; ScriptData = ScriptData.substr(ScriptData.indexOf("}") + 1).trim(); ScriptData = ScriptData.split(";"); for (let i = 0; i < ScriptData.length; i++) { @@ -5320,32 +5320,32 @@ async function main() { } else if (location.pathname == "/comparesource.php") { if (UtilityEnabled("CompareSource")) { if (location.search == "") { - document.querySelector("body > div.container > div").innerHTML = ""; + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").innerHTML = ""; let LeftCodeText = document.createElement("span"); - document.querySelector("body > div.container > div").appendChild(LeftCodeText); + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").appendChild(LeftCodeText); LeftCodeText.innerText = "左侧代码的运行编号:"; let LeftCode = document.createElement("input"); - document.querySelector("body > div.container > div").appendChild(LeftCode); + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").appendChild(LeftCode); LeftCode.classList.add("form-control"); LeftCode.style.width = "40%"; LeftCode.style.marginBottom = "5px"; let RightCodeText = document.createElement("span"); - document.querySelector("body > div.container > div").appendChild(RightCodeText); + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").appendChild(RightCodeText); RightCodeText.innerText = "右侧代码的运行编号:"; let RightCode = document.createElement("input"); - document.querySelector("body > div.container > div").appendChild(RightCode); + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").appendChild(RightCode); RightCode.classList.add("form-control"); RightCode.style.width = "40%"; RightCode.style.marginBottom = "5px"; let CompareButton = document.createElement("button"); - document.querySelector("body > div.container > div").appendChild(CompareButton); + if (document.querySelector("body > div.container > div") != null) document.querySelector("body > div.container > div").appendChild(CompareButton); CompareButton.innerText = "比较"; CompareButton.className = "btn btn-primary"; CompareButton.addEventListener("click", () => { location.href = "https://www.xmoj.tech/comparesource.php?left=" + Number(LeftCode.value) + "&right=" + Number(RightCode.value); }); } else { - document.querySelector("body > div > div.mt-3").innerHTML = ` + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = `
@@ -5391,7 +5391,7 @@ async function main() { } } else if (location.pathname == "/loginpage.php") { if (UtilityEnabled("NewBootstrap")) { - document.querySelector("#login").innerHTML = ` + if (document.querySelector("#login") != null) document.querySelector("#login").innerHTML = `
@@ -5421,7 +5421,7 @@ async function main() { let ErrorText = document.createElement("div"); ErrorText.style.color = "red"; ErrorText.style.marginBottom = "5px"; - document.querySelector("#login").appendChild(ErrorText); + if (document.querySelector("#login") != null) document.querySelector("#login").appendChild(ErrorText); let LoginButton = document.getElementsByName("submit")[0]; LoginButton.addEventListener("click", async () => { let Username = document.getElementsByName("user_id")[0].value; @@ -5472,14 +5472,14 @@ async function main() { (async () => { let Credential = await getCredential(); if (Credential) { - document.querySelector("#login > div:nth-child(1) > div > input").value = Credential.id; - document.querySelector("#login > div:nth-child(2) > div > input").value = Credential.password; + if (document.querySelector("#login > div:nth-child(1) > div > input") != null) document.querySelector("#login > div:nth-child(1) > div > input").value = Credential.id; + if (document.querySelector("#login > div:nth-child(2) > div > input") != null) document.querySelector("#login > div:nth-child(2) > div > input").value = Credential.password; LoginButton.click(); } })(); } } else if (location.pathname == "/contest_video.php" || location.pathname == "/problem_video.php") { - let ScriptData = document.querySelector("body > div > div.mt-3 > center > script").innerHTML; + let ScriptData = (document.querySelector("body > div > div.mt-3 > center > script") != null) ? document.querySelector("body > div > div.mt-3 > center > script").innerHTML : ""; if (document.getElementById("J_prismPlayer0").innerHTML != "") { document.getElementById("J_prismPlayer0").innerHTML = ""; if (player) { @@ -5530,15 +5530,15 @@ async function main() { DownloadButton.innerText = "下载"; DownloadButton.href = Response.PlayInfoList.PlayInfo[0].PlayURL; DownloadButton.download = Response.VideoBase.Title; - document.querySelector("body > div > div.mt-3 > center").appendChild(DownloadButton); + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").appendChild(DownloadButton); }); } } else if (location.pathname == "/reinfo.php") { document.title = "测试点信息: " + SearchParams.get("sid"); if (document.querySelector("#results > div") == undefined) { - document.querySelector("#results").parentElement.innerHTML = "没有测试点信息"; + if (document.querySelector("#results") != null) document.querySelector("#results").parentElement.innerHTML = "没有测试点信息"; } else { - for (let i = 0; i < document.querySelector("#results > div").children.length; i++) { + for (let i = 0; document.querySelector("#results > div") != null && i < document.querySelector("#results > div").children.length; i++) { let CurrentElement = document.querySelector("#results > div").children[i].children[0].children[0].children[0]; let Temp = CurrentElement.innerText.substring(0, CurrentElement.innerText.length - 2).split("/"); CurrentElement.innerText = TimeToStringTime(Temp[0]) + "/" + SizeToStringSize(Temp[1]); @@ -6070,7 +6070,7 @@ cerr< { let ParsedDocument = new DOMParser().parseFromString(Response, "text/html"); - return ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText; + return (ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)") != null) ? ParsedDocument.querySelector("#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)").innerText : ""; }); await new Promise((Resolve) => { @@ -6150,7 +6150,7 @@ cerr< div").appendChild(Container); + if (document.querySelector("body > div") != null) document.querySelector("body > div").appendChild(Container); Container.className = "mt-3"; Container.appendChild(SoftwareList); if (UtilityEnabled("NewDownload")) { @@ -6220,26 +6220,26 @@ cerr< div > div.mt-3 > center").insertBefore(document.querySelector("#statics"), document.querySelector("body > div > div.mt-3 > center > table")); - document.querySelector("body > div > div.mt-3 > center").insertBefore(document.querySelector("#problemstatus"), document.querySelector("body > div > div.mt-3 > center > table")); + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").insertBefore(document.querySelector("#statics"), document.querySelector("body > div > div.mt-3 > center > table")); + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").insertBefore(document.querySelector("#problemstatus"), document.querySelector("body > div > div.mt-3 > center > table")); - document.querySelector("body > div > div.mt-3 > center > table:nth-child(3)").remove(); - let Temp = document.querySelector("#statics").rows; + if (document.querySelector("body > div > div.mt-3 > center > table:nth-child(3)") != null) document.querySelector("body > div > div.mt-3 > center > table:nth-child(3)").remove(); + let Temp = (document.querySelector("#statics") != null) ? document.querySelector("#statics").rows : []; for (let i = 0; i < Temp.length; i++) { Temp[i].removeAttribute("class"); } - document.querySelector("#problemstatus > thead > tr").innerHTML = document.querySelector("#problemstatus > thead > tr").innerHTML.replaceAll("td", "th"); - document.querySelector("#problemstatus > thead > tr > th:nth-child(2)").innerText = "运行编号"; - document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); - document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); - document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); - document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); - Temp = document.querySelector("#problemstatus > thead > tr").children; + if (document.querySelector("#problemstatus > thead > tr") != null) document.querySelector("#problemstatus > thead > tr").innerHTML = document.querySelector("#problemstatus > thead > tr").innerHTML.replaceAll("td", "th"); + if (document.querySelector("#problemstatus > thead > tr > th:nth-child(2)") != null) document.querySelector("#problemstatus > thead > tr > th:nth-child(2)").innerText = "运行编号"; + if (document.querySelector("#problemstatus > thead > tr > th:nth-child(4)") != null) document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); + if (document.querySelector("#problemstatus > thead > tr > th:nth-child(4)") != null) document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); + if (document.querySelector("#problemstatus > thead > tr > th:nth-child(4)") != null) document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); + if (document.querySelector("#problemstatus > thead > tr > th:nth-child(4)") != null) document.querySelector("#problemstatus > thead > tr > th:nth-child(4)").remove(); + Temp = (document.querySelector("#problemstatus > thead > tr") != null) ? document.querySelector("#problemstatus > thead > tr").children : []; for (let i = 0; i < Temp.length; i++) { Temp[i].removeAttribute("class"); } - Temp = document.querySelector("#problemstatus > tbody").children; + Temp = (document.querySelector("#problemstatus > tbody") != null) ? document.querySelector("#problemstatus > tbody").children : []; for (let i = 0; i < Temp.length; i++) { if (Temp[i].children[5].children[0] != null) { Temp[i].children[1].innerHTML = `${escapeHTML(Temp[i].children[1].innerText.trim())}`; @@ -6260,14 +6260,14 @@ cerr<«
  • ` + (CurrentPage)}
  • `; } Pagination += `
  • ` + (CurrentPage + 1)}
  • `; - if (document.querySelector("#problemstatus > tbody").children != null && document.querySelector("#problemstatus > tbody").children.length == 20) { + if (document.querySelector("#problemstatus > tbody") != null && document.querySelector("#problemstatus > tbody").children != null && document.querySelector("#problemstatus > tbody").children.length == 20) { Pagination += `
  • ` + (CurrentPage + 2) + `
  • »
  • `; } Pagination += ``; - document.querySelector("body > div > div.mt-3 > center").innerHTML += Pagination; + if (document.querySelector("body > div > div.mt-3 > center") != null) document.querySelector("body > div > div.mt-3 > center").innerHTML += Pagination; } else if (location.pathname == "/problem_solution.php") { if (UtilityEnabled("RemoveUseless")) { - document.querySelector("h2.lang_en").remove(); //fixes #332 + if (document.querySelector("h2.lang_en") != null) document.querySelector("h2.lang_en").remove(); //fixes #332 } if (UtilityEnabled("CopyMD")) { await fetch(location.href).then((Response) => { @@ -6279,7 +6279,7 @@ cerr< div > div.mt-3 > center > h2").appendChild(CopyMDButton); + if (document.querySelector("body > div > div.mt-3 > center > h2") != null) document.querySelector("body > div > div.mt-3 > center > h2").appendChild(CopyMDButton); CopyMDButton.addEventListener("click", () => { GM_setClipboard(GetMDText(ParsedDocument.querySelector("body > div > div > div")).trim().replaceAll("\n\t", "\n").replaceAll("\n\n", "\n")); CopyMDButton.innerText = "复制成功"; @@ -6304,7 +6304,7 @@ cerr< div > div.mt-3 > div > div.col-md-8").children; + let Temp = (document.querySelector("body > div > div.mt-3 > div > div.col-md-8") != null) ? document.querySelector("body > div > div.mt-3 > div > div.col-md-8").children : []; let NewsData = []; for (let i = 0; i < Temp.length; i += 2) { let Title = Temp[i].children[0].innerText; @@ -6315,7 +6315,7 @@ cerr< div > div.mt-3 > div > div.col-md-8").innerHTML = ""; + if (document.querySelector("body > div > div.mt-3 > div > div.col-md-8") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-8").innerHTML = ""; for (let i = 0; i < NewsData.length; i++) { let NewsRow = document.createElement("div"); NewsRow.className = "cnt-row"; @@ -6330,11 +6330,11 @@ cerr< div > div.mt-3 > div > div.col-md-8").appendChild(NewsRow); + if (document.querySelector("body > div > div.mt-3 > div > div.col-md-8") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-8").appendChild(NewsRow); } - let MyContestData = document.querySelector("body > div > div.mt-3 > div > div.col-md-4 > div:nth-child(2)").innerHTML; - let CountDownData = document.querySelector("#countdown_list").innerHTML; - document.querySelector("body > div > div.mt-3 > div > div.col-md-4").innerHTML = `
    + let MyContestData = (document.querySelector("body > div > div.mt-3 > div > div.col-md-4 > div:nth-child(2)") != null) ? document.querySelector("body > div > div.mt-3 > div > div.col-md-4 > div:nth-child(2)").innerHTML : ""; + let CountDownData = (document.querySelector("#countdown_list") != null) ? document.querySelector("#countdown_list").innerHTML : ""; + if (document.querySelector("body > div > div.mt-3 > div > div.col-md-4") != null) document.querySelector("body > div > div.mt-3 > div > div.col-md-4").innerHTML = `
    我的月赛
    ${MyContestData}
    @@ -6370,7 +6370,7 @@ cerr< div > div.mt-3").innerHTML = ``; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = ``; CodeMirror.fromTextArea(document.querySelector("body > div > div.mt-3 > textarea"), { lineNumbers: true, mode: "text/x-c++src", @@ -6384,10 +6384,10 @@ cerr< { let ParsedDocument = new DOMParser().parseFromString(Result, "text/html"); if (!ParsedDocument.getElementsByClassName("jumbotron")[0].innerHTML.includes('I am sorry, You could not view this message!')) { - document.querySelector("body > div > div.mt-3").innerHTML = ""; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = ""; let CodeElement = document.createElement("div"); CodeElement.className = "mb-3"; - document.querySelector("body > div > div.mt-3").appendChild(CodeElement); + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").appendChild(CodeElement); CodeMirror(CodeElement, { value: ParsedDocument.getElementById("errtxt").innerHTML.replaceAll("<", "<").replaceAll(">", ">"), lineNumbers: true, @@ -6405,11 +6405,11 @@ cerr< div > div.mt-3").innerHTML = ""; + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = ""; for (let i = 0; i < Temp.length; i++) { let CodeElement = document.createElement("div"); CodeElement.className = "mb-3"; - document.querySelector("body > div > div.mt-3").appendChild(CodeElement); + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").appendChild(CodeElement); CodeMirror(CodeElement, { value: Temp[i].innerText, lineNumbers: true, @@ -6425,7 +6425,7 @@ cerr< div > div.mt-3").innerHTML = `
    + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = `
    @@ -6522,7 +6522,7 @@ cerr< div > div.mt-3").innerHTML = `
    + if (document.querySelector("body > div > div.mt-3") != null) document.querySelector("body > div > div.mt-3").innerHTML = `
    @@ -6681,7 +6681,7 @@ cerr< div > div").innerHTML = `

    讨论列表${(isNaN(ProblemID) ? "" : ` - 题目` + ProblemID)}

    + if (document.querySelector("body > div > div") != null) document.querySelector("body > div > div").innerHTML = `

    讨论列表${(isNaN(ProblemID) ? "" : ` - 题目` + ProblemID)}