From c4c268fdf3e0e11945cba3b8c8b90a3c44fef208 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8C=97=E6=9E=81=E5=B0=8F=E7=8B=90?=
<60805870+beijixiaohu@users.noreply.github.com>
Date: Fri, 12 Jul 2024 10:45:49 +0800
Subject: [PATCH] =?UTF-8?q?fix(Codeforces):=20=E6=94=B9=E8=BF=9B"=E8=AF=84?=
=?UTF-8?q?=E6=B5=8B=E7=8A=B6=E6=80=81=E6=96=87=E6=9C=AC=E6=9B=BF=E6=8D=A2?=
=?UTF-8?q?"=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=B7=BB=E5=8A=A0=20"inqueue"=20?=
=?UTF-8?q?=E6=A0=87=E8=AF=86=E7=AC=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../locales/codeforces-better/settings.json | 2 +-
script/dev/codeforces-better.user.js | 114 +++++++++++++++---
2 files changed, 95 insertions(+), 21 deletions(-)
diff --git a/resources/locales/codeforces-better/settings.json b/resources/locales/codeforces-better/settings.json
index 8be49bb66..753f1c5eb 100644
--- a/resources/locales/codeforces-better/settings.json
+++ b/resources/locales/codeforces-better/settings.json
@@ -393,7 +393,7 @@
},
"judgeStatusReplaceText": {
"title": "评测状态文本替换",
- "helpText": "
将题目的评测状态文本替换为指定的文本。
支持的变量:
{Status}
评测结果的完整描述,例如 \"Accepted\"。
{Stat}
评测结果的缩写形式,例如 \"AC\"。
{Number}
评测结果中的最后一个数字,评测状态为AC时不显示。
{标识符:xxx}
当标识符为真时显示括号内的内容。支持的标识符:ac
、wa
、tle
、mle
、re
、ce
、hacked
、skipped
、ile
、pc
、pending
示例:
我怎么{Stat}了,{wa:呜呜}
此时如果评测结果为\"Wrong answer\",则会显示:
我怎么WA了,呜呜
",
+ "helpText": "将题目的评测状态文本替换为指定的文本。
支持的变量:
{Status}
评测结果的完整描述,例如 \"Accepted\"。
{Stat}
评测结果的缩写形式,例如 \"AC\"。
{Number}
评测结果中的最后一个数字,评测状态为AC时不显示。
{标识符:xxx}
当标识符为真时显示括号内的内容。支持的标识符:ac
、wa
、tle
、mle
、re
、ce
、hacked
、skipped
、ile
、pc
、pending
、inqueue
示例:
我怎么{Stat}了,{wa:呜呜}
此时如果评测结果为\"Wrong answer\",则会显示:
我怎么WA了,呜呜
",
"placeholder": "请输入替换的模式,为空则不替换。"
}
},
diff --git a/script/dev/codeforces-better.user.js b/script/dev/codeforces-better.user.js
index f26ca8e24..4186b817f 100644
--- a/script/dev/codeforces-better.user.js
+++ b/script/dev/codeforces-better.user.js
@@ -1,7 +1,7 @@
// ==UserScript==
// @name Codeforces Better!
// @namespace https://greasyfork.org/users/747162
-// @version 1.76.5
+// @version 1.76.6
// @author 北极小狐
// @match *://*.codeforces.com/*
// @match *://*.codeforc.es/*
@@ -6140,7 +6140,7 @@ const preference_settings_HTML = `
${helpCircleHTML}
-
+
`;
@@ -10106,16 +10106,18 @@ const StatusAcronyms = {
"Idleness limit exceeded": "ILE",
"Perfect result:": "AC",
"Partial result:": "PC",
- "Running": "PENDING"
+ "Running": "PENDING",
+ "In queue": "INQUEUE"
};
/**
* 评测结果的颜色
*/
const StatusColors = {
- "AC": "#52c41a",
+ "AC": "#0a0",
"WA": "#e74c3c",
"PENDING": "#808080",
+ "INQUEUE": "#808080",
};
/**
@@ -10233,7 +10235,8 @@ async function judgeStatusReplace() {
skipped: statusAcronym === "Skipped",
ile: statusAcronym === "ILE",
pc: statusAcronym === "PC",
- pending: statusAcronym === "PENDING"
+ pending: statusAcronym === "PENDING",
+ inqueue: statusAcronym === "INQUEUE",
}
const final_result = parseTemplate(result, statusMap);
return final_result;
@@ -10241,7 +10244,7 @@ async function judgeStatusReplace() {
/**
* 处理评测结果
- * @param {string} text 代替换的文本
+ * @param {string} text 待替换的文本
* @returns {object} 处理后的文本和颜色
*/
const process = (text) => {
@@ -10264,26 +10267,97 @@ async function judgeStatusReplace() {
OJB_observeElement({
selector: '.datatable',
callback: (node) => {
+ /**
+ * 更新元素
+ * @param {HTMLElement} element - 要更新的元素
+ */
const updateElement = (element) => {
- const { text, color } = process($(element).text());
- $(element).text(text);
- $(element).css({
- "color": color,
- "font-weight": "700"
- });
+
+ /**
+ * 替换文本并着色
+ * @param {HTMLElement} element - 要处理的元素
+ */
+ const replaceAndColor = (element) => {
+ const { text, color } = process(element.textContent);
+ element.textContent = text;
+ element.style.color = color;
+ element.style.fontWeight = '700';
+ };
+
+ /**
+ * 获取最小目标元素
+ * @param {HTMLElement} element - 要检查的元素
+ * @returns {HTMLElement} - 最小目标元素
+ */
+ const getMinElement = (element) => {
+ // 先获取一次text值
+ const { text: originalText } = process(element.textContent);
+
+ /**
+ * 深搜
+ * @param {HTMLElement} el - 当前遍历的元素
+ * @returns {HTMLElement} - 能维持text不变的最小子元素
+ */
+ const findMinElement = (el) => {
+ // 遍历子元素
+ for (let child of el.children) {
+ // 获取子元素的处理后的text值
+ const { text: childText } = process(child.textContent);
+
+ // 如果子元素的text与原始text相同,递归检查子元素
+ if (childText === originalText) {
+ return findMinElement(child);
+ }
+ }
+
+ // 如果没有子元素能维持text不变,返回当前元素
+ return el;
+ };
+
+ // 从初始元素开始递归
+ return findMinElement(element);
+ };
+
+ // 获取最小目标元素
+ const minElement = getMinElement(element);
+ // 替换文本并着色
+ replaceAndColor(minElement);
};
- // 选择器
- const selectorCondition = "[class^='verdict-'], [submissionverdict='COMPILATION_ERROR']";
+ /**
+ * 判断该元素是否在 .status-verdict-cell 内,
+ * 检查直到确认是或者遇到了 .datatable 或没有上层元素
+ *
+ * @param {Element} element - 要检查的元素
+ * @returns {Element|null} - 如果是,则返回对应的 .status-verdict-cell 元素,否则返回 null
+ * @throws {TypeError} - 如果提供的值不是有效的 DOM 元素
+ */
+ const isDescendantOfStatusVerdictCell = (element) => {
+ if (!(element instanceof Element)) {
+ throw new TypeError('The provided value is not a valid DOM element.');
+ }
+
+ let currentElement = element;
+
+ while (currentElement && !currentElement.matches('.datatable')) {
+ if (currentElement.matches('.status-verdict-cell')) {
+ return currentElement;
+ }
+ currentElement = currentElement.parentElement;
+ }
+
+ return null;
+ };
- // 检查[node]本身是否符合选择器条件
- if ($(node).is(selectorCondition)) {
- updateElement(node);
+ // 检查变动元素是否在 .status-verdict-cell 内
+ const statusVerdictCell = isDescendantOfStatusVerdictCell(node);
+ if (statusVerdictCell) {
+ updateElement(statusVerdictCell);
}
- // 更新[node]内部符合选择器条件的所有元素
- $(node).find(selectorCondition).each(function () {
- updateElement(this);
+ // 检查node内部所有的 .status-verdict-cell 元素
+ node.querySelectorAll('.status-verdict-cell').forEach(element => {
+ updateElement(element);
});
}
});