// ==UserScript==
// @name vjudge++
// @namespace vjudge-plus-v2
// @version 1.8.4b3
// @description 为vJudge设置背景,并汉化部分界面
// @author axototl (original by Suntra)
// @match https://vjudge.net/*
// @noframes
// @icon https://vjudge.net/favicon.ico
// @license AGPLv3 or later
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-end
// ==/UserScript==
// license text: https://www.gnu.org/licenses/agpl-3.0.txt
let experimental = false;
function getVal(key, def) {
let gg = GM_getValue(key);
if (gg === '' || gg === undefined) {
GM_setValue(key, def);
gg = def;
}
return gg;
}
function reloader() {
if (!navigator.onLine) {
alert("离线状态,无法重加载。\n修改无法即刻生效");
return;
}
alert("设置成功,刷新生效");
location.reload();
}
const loginBoxTranslate = {
"#loginModalLabel": "登录",
"#btn-forget-password": "忘记密码",
"#btn-login": "登录"
};
const registerBoxTrans = {
"#registerModalLabel": "注册",
"[for=register-username]": "用户名\n(必填)",
"[for=register-password]": "密码\n(必填)",
"[for=register-repeat-password]": "重复密码\n(必填)",
"[for=register-nickname]": "昵称\n(可修改)",
"[for=register-school]": "学校",
"[for=register-email]": "邮箱\n(必填)",
"[for=register-introduction]": "自我介绍",
"[for=register-captcha]": "验证码\n(必填)",
"#btn-register": "注册",
};
const translateTable = {
"#nav-problem > a": "问题列表",
"#nav-status > a": "提交记录",
"#nav-contest > a": "比赛",
"#nav-workbook > a": "题单",
"#nav-user > a": "用户",
"#nav-group > a": "小组",
"#nav-comment > a": "留言板",
".navbar-brand": "vJudge",
".login": "登录",
".register": "注册",
};
function upd_trans(tr) {
if (!experimental) return;
for (let prop in tr) {
let k = document.querySelector(prop);
if(null != k) k.innerText = tr[prop];
}
}
function reg_box_trans(triggerElem_selector, table) {
let s = document.querySelector(triggerElem_selector);
if (null != s) s.addEventListener("click", () => setTimeout(() => upd_trans(table), 50));
}
(async function() {
experimental = getVal("experimental", false);
upd_trans(translateTable);
//设置实验性功能
(() => {
let flag = true;
const prompt = ["× 点击启用实验性功能(界面汉化等)", "✔ 点击关闭实验性功能"]
GM_registerMenuCommand(prompt[experimental | 0], () => {
if (flag) {
experimental = !experimental;
GM_setValue("experimental", experimental);
flag = false;
}
reloader();
});
})();
//在基于 Blink 浏览器上检测是否为正常返回
if (navigator.userAgent.includes("Chrome") && performance.getEntries()[0].responseStatus != 200) return;
// 设置背景
let back = getVal("background", "https://cdn.luogu.com.cn/images/bg/fe/Day_And_Night_1.jpg");
GM_registerMenuCommand("设置背景URL", () => {
back = window.prompt("请输入背景URL", back);
GM_setValue("background", back);
reloader();
});
// 设置文字颜色
let col = getVal("col", "#b93e3e");
const tes = /^#([0-9a-f]{3,4}|[0-9a-f]{6})$/i;
function getColor(t) {
do {
tmp = window.prompt("请输入颜色的Hexcode\n(比如#b93e3e)\n建议选择背景主色调的反差色", t);
} while (!tes.test(t));
return t;
}
GM_registerMenuCommand("设置文字颜色", () => {
GM_setValue("col", getColor(col));
reloader();
});
let collink = getVal("collink", "#ff4c8c");
GM_registerMenuCommand("设置链接背景颜色", () => {
GM_setValue("collink", getColor(collink));
reloader();
});
document.body.innerHTML = "<div style='height: 60px'></div>" + document.body.innerHTML; // 防止顶栏和页面内容重叠
// User defined style
GM_addStyle("body {background: url("+back+") no-repeat center top fixed;background-size: 100% 100%;-moz-background-size: 100% 100%;color: "+col+";}"+
"a:focus, a:hover {color: "+collink+";text-decoration: underline;}");
// Global Style
GM_addStyle(
".navbar {border-radius:0rem;background-color: rgba(0,0,0,65%) !important;position: fixed;top: 0;left: 0;z-index: 1000;width: 100%;}"+
"scrollbar-width: none"+
"#prob-ads {display: none;}"+ // 屏蔽广告
"#img-support {display: none;}"+ // 屏蔽 sponsor 栏广告
".card-block, .card, .list-group-item, .btn-secondary, .page-link, .page-item.disabled .page-link, .dropdown-menu {background-color: rgba(255,255,255,65%)!important;}"+
".modal-content {background-color: rgba(255,255,255,90%);}"+
".form-control {background-color: rgba(255,255,255,50%);}"+
".tab-content {background-color: rgba(255,255,255,50%);border: 2px solid #eceeef;border-radius: 0.25rem;padding: 20px;}"+
"table {background-color: rgba(255,255,255,70%);border-radius: 0.25rem;}"
);
reg_box_trans(".login", loginBoxTranslate);
reg_box_trans(".register", registerBoxTrans);
document.querySelector("body > div.body-footer").innerHTML += '<p style="color: #3fb98b">Theme powered by vjudge++ (original by <a href="https://greasyfork.org/scripts/448801">vjudge+</a>)</p>';
})();