2024/1/23 15:25:23
当前为
// ==UserScript==
// @name becoder
// @namespace Violentmonkey Scripts
// @match https://www.becoder.com.cn/*
// @grant none
// @version 1.9
// @author EarthMessenger
// @description 2024/1/23 15:25:23
// @grant GM.getValue
// @grant unsafeWindow
// @license MIT
// ==/UserScript==
(() => {
// utilities BEGIN
const removeNode = (element) => {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
};
const injectCSS = (css) => {
const style = document.createElement('style');
style.innerHTML = css;
document.head.appendChild(style);
};
// utilities END
const fixRightClick = () => {
unsafeWindow.oncontextmenu = null;
document.oncontextmenu = null;
};
const fixPDF = () => {
const iframes = document.querySelectorAll("iframe");
const pat =
/https:\/\/www\.becoder\.com\.cn\/js\/pdf\/web\/viewer\.html\?file=(\S*)/gm;
for (const oldPdf of iframes) {
const res = pat.exec(oldPdf.src);
if (res == null) continue;
const url = res[1];
fetch(url)
.then((resp) => resp.blob())
.then((blob) => blob.slice(0, blob.size, "application/pdf"))
.then((blob) => {
const newPdf = document.createElement("iframe");
newPdf.src = URL.createObjectURL(blob);
newPdf.width = oldPdf.width;
newPdf.height = oldPdf.height;
const parent = oldPdf.parentNode;
parent.replaceChild(newPdf, oldPdf);
});
}
};
const fixHomePage = () => {
if (window.location.pathname !== "/index") return;
const mainContent = document.querySelector("body > main.main-content");
removeNode(mainContent.querySelector(".carousel")); // AI 頭圖
removeNode(mainContent.querySelector(".side-column > div:nth-child(2)")); // 提交統計
};
const redirectHomePage = () => {
if (window.location.pathname === "/") {
window.location.replace(new URL("/index", location.href).toString());
}
};
const fillLoginCredentials = async () => {
if (window.location.pathname !== "/login") return;
// 根據 https://wiki.greasespot.net/GM.getValue,GM.getValue 應該是不支持 object 的,
// 但是相信 2025 年不會有人使用 Greasemonkey 的。而且 Tampermonkey 和 Violentmonkey 都支持,
// 那就假裝它確實是可行的。
const credentials = await GM.getValue("credentials");
if (credentials === undefined) return;
try {
const {username, password} = credentials;
document.getElementById("username").value = username;
document.getElementById("password").value = password;
const captcha = document.getElementById("captcha");
const autoSubmitCaptcha = (ev) => {
if (ev.target.value.length !== 4) return ;
unsafeWindow.login();
};
captcha.addEventListener("input", autoSubmitCaptcha);
captcha.focus();
} catch (error) {
console.error("填寫的憑據無效。");
}
};
const fixNavbar = () => {
const body = document.body;
const navbar = document.querySelector("body > nav > div");
if (navbar === null) return;
navbar.children[0].href = "/index"; // 舊主頁
const navbarNav = navbar.children[1];
removeNode(navbarNav.children[6]); // 工具
removeNode(navbarNav.children[5]); // 課程
removeNode(navbarNav.children[0]); // 首頁
navbar.children[0].href = "/index"; // 使用舊首頁
};
const removeUndeletedStuff = () => {
document.querySelectorAll("body > div.ui.main.container")
.forEach((ele) => {
removeNode(ele);
});
Array.from(document.querySelectorAll("body > nav")) // NodeList is not array
.slice(0, -1)
.forEach((ele) => {
removeNode(ele);
});
};
const fixPadding = () => {
// copied from homepage
injectCSS(`
.main-content {
margin-top: 20px;
min-height: calc(100vh - 20px);
padding: 1rem;
max-width: 1200px;
width: 92%;
margin-left: auto;
margin-right: auto;
}
@media (max-width: 768px) {
.main-content {
width: 94%;
padding: 0.75rem;
}
}
@media (max-width: 480px) {
.main-content {
width: 96%;
padding: 0.5rem;
}
}
`);
const mainContent = document.querySelector("body > div.padding") || document.querySelector("body > span#submission_content > div.padding");
if (mainContent) {
mainContent.className = "main-content";
}
};
redirectHomePage();
fixRightClick();
removeUndeletedStuff();
fixPDF();
fixHomePage();
fillLoginCredentials();
fixNavbar();
fixPadding();
})();