toolkit
// ==UserScript==
// @name toolkit - Theo
// @namespace http://tampermonkey.net/
// @version 2026.08.06
// @description toolkit
// @author Theo·Chan
// @license AGPL
// @match *://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant GM_registerMenuCommand
// ==/UserScript==
(function () {
'use strict';
console.log('toolkit - Theo');
//--------------------------复制为Markdown链接----------------------------------------------------//
// 注册右键菜单项
GM_registerMenuCommand('复制为Markdown链接', () => {
const markdownLink = `[${document.title}](${window.location.href})`;
console.log(markdownLink);
// 复制到剪贴板
copyText(markdownLink);
});
function copyText(markdownLink) {
let _nav = window.navigator;
// 优先使用 Clipboard API
if (_nav.isPrototypeOf('clipboard') && _nav.clipboard && window.isSecureContext) {
_nav.clipboard.writeText(markdownLink)
.then(() => createToast("已复制为Markdown链接"))
.catch(() => fallbackCopy(markdownLink));
} else {
fallbackCopy(markdownLink);
}
}
function fallbackCopy(text) {
const textarea = document.createElement("textarea");
textarea.value = text;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand("copy");
createToast("已复制为Markdown链接:<br/>" + text);
} catch (err) {
createToast("复制失败,请手动复制:<br/>" + text, false, 10000);
}
document.body.removeChild(textarea);
}
// 创建提示框元素
const createToast = (content, isSuccess = true, timeOut = 1500) => {
const toast = document.createElement('div');
toast.innerHTML = content;
toast.style = `
position: fixed;
word-break: break-all;
top: 20px;
left: 50%;
transform: translateX(-50%);
padding: 12px 24px;
color: ${isSuccess ? '#4CAF50' : '#F44336'};
border-radius: 4px;
z-index: 99999;
opacity: 1;
background-color: ${isSuccess ? 'rgb(34 57 54 / 80%)' : 'rgb(254 225 164 / 80%)'};
transition: opacity 0.5s ease-out;
`;
document.body.appendChild(toast);
// 触发淡出
setTimeout(() => {
toast.style.opacity = 0;
toast.addEventListener('transitionend', () => {
toast.remove();
}, { once: true });
}, timeOut); // 显示 1.5 秒后开始淡出
return toast;
};
// pc QQ 安全提醒页面的自动跳转
function qqAutoGo() {
if (window.location.hostname !== 'c.pc.qq.com' || window.location.pathname !== '/middlem.html') {
return;
}
const pfUrl = new URLSearchParams(window.location.search).get('pfurl');
if (!pfUrl) {
return;
}
let targetUrl;
try {
targetUrl = decodeURIComponent(pfUrl);
} catch (error) {
targetUrl = pfUrl;
}
const container = document.querySelector('.url-container');
if (!container) {
console.warn('未找到 .url-container 元素,无法显示倒计时跳转提示。');
// 等待 1 秒后重试
setTimeout(qqAutoGo, 1000);
return;
}
var countdown = 10;
const wrapper = document.createElement('div');
wrapper.style.cssText = 'display:inline-flex;align-items:center;flex-wrap:wrap;gap:10px;margin-top:10px;';
const countdownValue = document.createElement('span');
countdownValue.style.cssText = 'font-weight:600;';
countdownValue.textContent = `${countdown}`;
countdownValue.title = '剩余秒数';
const countdownLabel = document.createElement('span');
countdownLabel.style.cssText = 'display:inline-flex;align-items:center;gap:5px;font-size:14px;color:#e96725;';
countdownLabel.appendChild(countdownValue);
countdownLabel.appendChild(document.createTextNode('秒后跳转,按 Esc 取消'));
const jumpLink = document.createElement('a');
jumpLink.href = targetUrl;
jumpLink.textContent = '立即跳转';
jumpLink.style.cssText = 'color:var(--brand_standard);text-decoration:underline;cursor:pointer;font-size:14px;';
jumpLink.title = '点击立即跳转到目标页面';
wrapper.append(countdownLabel);
container.parentNode.insertBefore(jumpLink, container.nextSibling);
container.parentNode.insertBefore(wrapper, container.nextSibling);
let cancelled = false;
const cleanup = () => {
window.clearInterval(intervalId);
document.removeEventListener('keydown', onKeyDown);
};
const cancelJump = () => {
if (cancelled) {
return;
}
cancelled = true;
cleanup();
countdownLabel.innerHTML = '已取消跳转';
createToast('已取消自动跳转', true, 2000);
};
const onKeyDown = (event) => {
if (event.key === 'Escape' || event.key === 'Esc') {
cancelJump();
}
};
const tick = () => {
countdown -= 1;
if (countdown <= 0) {
cleanup();
window.location.href = targetUrl;
return;
}
countdownValue.textContent = `${countdown}`;
};
const intervalId = window.setInterval(tick, 1000);
document.addEventListener('keydown', onKeyDown);
}
qqAutoGo();
}) ();