// ==UserScript==
// @name Base64编码解码
// @namespace http://tampermonkey.net/
// @version 0.0.2
// @description 为水源恢复Base64解码和编码
// @author 艾伦·走路人 & Rosmontis
// @match https://shuiyuan.sjtu.edu.cn/*
// @license WTFPL
// @grant none
// ==/UserScript==
// 创建观察者实例
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === "childList") {
const list = document.querySelector(
".toolbar-popup-menu-options .select-kit-collection"
);
if (list) {
let encodeIcon = document.createElementNS(
"http://www.w3.org/2000/svg",
"use"
);
encodeIcon.setAttribute("href", "#far-eye-slash");
let base64EncodeIcon = encodeIcon.outerHTML;
addButtonToList(
list,
"base64-encode",
base64EncodeIcon,
"Base64编码",
encode
);
let decodeIcon = document.createElementNS(
"http://www.w3.org/2000/svg",
"use"
);
decodeIcon.setAttribute("href", "#far-eye");
let base64DecodeIcon = decodeIcon.outerHTML;
addButtonToList(
list,
"base64-decode",
base64DecodeIcon,
"Base64解码",
decode
);
}
}
}
});
// 开始观察文档的子节点变化
observer.observe(document.body, { childList: true, subtree: true });
// 添加按钮的函数
function addButtonToList(list, id, icon, text, action) {
// 检查按钮是否已经存在
if (!list.querySelector('li[data-guid="' + id + '"]')) {
// 创建新的li元素
const newItem = document.createElement("li");
newItem.setAttribute("data-guid", id);
newItem.setAttribute("role", "menuitemradio");
newItem.setAttribute("tabindex", "0");
newItem.classList.add("select-kit-row", "dropdown-select-box-row");
// 添加图标
const iconDiv = document.createElement("div");
iconDiv.classList.add("icons");
const iconSvg = document.createElementNS(
"http://www.w3.org/2000/svg",
"svg"
);
iconSvg.classList.add("fa", "d-icon", "svg-icon", "svg-string");
iconSvg.innerHTML = icon;
iconDiv.appendChild(iconSvg);
newItem.appendChild(iconDiv);
// 添加文字
const textDiv = document.createElement("div");
textDiv.classList.add("texts");
const textSpan = document.createElement("span");
textSpan.classList.add("name");
textSpan.textContent = text;
textDiv.appendChild(textSpan);
newItem.appendChild(textDiv);
// 添加点击事件
newItem.addEventListener("click", () => {
// 获取当前的 textarea
let textarea = document.querySelector("textarea");
let start = textarea.selectionStart;
let end = textarea.selectionEnd;
let selectedText = textarea.value.substring(start, end);
let newText = action(selectedText);
textarea.value =
textarea.value.substring(0, start) +
newText +
textarea.value.substring(end);
simulateTypeAndDelete(textarea);
textarea.selectionStart = start;
textarea.selectionEnd = start + newText.length;
});
// 将新元素添加到列表中
list.appendChild(newItem);
}
}
function encode(str) {
return btoa(encodeURIComponent(str));
}
function decode(base64) {
return decodeURIComponent(atob(base64));
}
function simulateTypeAndDelete(textareaElement) {
// 将 textarea 设置为焦点
textareaElement.focus();
// 模拟输入 '0'
let inputEvent = new InputEvent("input", {
bubbles: true,
cancelable: true,
inputType: "insertText",
data: "0",
});
// 创建一个键盘事件,模拟按下 '0' 键
let keydownEvent = new KeyboardEvent("keydown", {
key: "0",
keyCode: 48,
which: 48,
bubbles: true,
cancelable: true,
});
// 派发键盘事件和输入事件,模拟输入 '0'
textareaElement.dispatchEvent(keydownEvent);
textareaElement.dispatchEvent(inputEvent);
// 模拟 Backspace 键盘事件
let backspaceEvent = new KeyboardEvent("keydown", {
key: "Backspace",
keyCode: 8,
which: 8,
bubbles: true,
cancelable: true,
});
// 派发 Backspace 键盘事件
textareaElement.dispatchEvent(backspaceEvent);
}