// ==UserScript==
// @name 123pan JSON秒传链接工具
// @namespace http://tampermonkey.net/
// @version 1.1.9
// @description 1.1.9:修复bug
// @author Tocpomk
// @match *://*.123pan.com/*
// @match *://*.123pan.cn/*
// @match *://*.123865.com/*
// @match *://*.123684.com/*
// @match *://*.123912.com/*m
// @grant GM_addStyle
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-end
// @license MIT
// ==/UserScript==
(function() {
'use strict';
GM_addStyle(`
#json-tool-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
visibility: hidden;
transition: all 0.4s cubic-bezier(0.32, 0.72, 0, 1);
pointer-events: none;
}
#json-tool-modal.show {
opacity: 1;
visibility: visible;
pointer-events: all;
}
#json-tool-content {
width: 90%;
height: 90%;
max-width: 1200px;
background: white;
border-radius: 16px;
box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
display: flex;
flex-direction: column;
overflow: hidden;
transform: translateY(50px) scale(0.95);
opacity: 0;
transition: all 0.5s cubic-bezier(0.32, 0.72, 0, 1);
}
#json-tool-modal.show #json-tool-content {
transform: translateY(0) scale(1);
opacity: 1;
}
#json-tool-close {
background: rgba(0,0,0,0.2);
border: none;
color: white;
font-size: 26px;
cursor: pointer;
width: 36px;
height: 36px;
border-radius: 50%;
transition: all 0.3s ease;
z-index: 10001;
display: flex;
align-items: center;
justify-content: center;
position: static;
}
#json-tool-close:hover {
background: rgba(0,0,0,0.5);
transform: scale(1.15) rotate(90deg);
}
#json-tool-iframe {
width: 100%;
height: 100%;
border: none;
border-radius: 0 0 16px 16px;
}
#json-tool-header {
height: 60px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
color: white;
font-weight: bold;
font-size: 18px;
position: relative;
}
#json-tool-title {
display: flex;
align-items: center;
gap: 12px;
}
#json-tool-title svg {
width: 24px;
height: 24px;
fill: white;
}
.json-tool-drag-handle {
width: 100%;
height: 30px;
position: absolute;
top: 0;
left: 0;
cursor: move;
z-index: 1;
}
@media (max-width: 768px) {
#json-tool-content {
width: 95%;
height: 95%;
}
#json-tool-header {
padding: 0 15px;
height: 50px;
font-size: 16px;
}
}
#json-tool-header-btns {
display: flex;
align-items: center;
gap: 12px;
position: absolute;
top: 50%;
right: 18px;
transform: translateY(-50%);
z-index: 10001;
}
#json-tool-maximize,
#json-tool-close {
background: rgba(0,0,0,0.2);
border: none;
color: white;
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
padding: 0;
margin: 0;
position: static;
}
#json-tool-maximize:hover,
#json-tool-close:hover {
background: rgba(0,0,0,0.4);
transform: scale(1.1);
}
#json-tool-maximize svg,
#json-tool-close svg {
width: 22px;
height: 22px;
display: block;
margin: auto;
fill: white;
}
.json-tool-menu-item.selected, .json-tool-menu-item.active, .json-tool-menu-item:active {
background: rgb(96, 126, 252) !important;
}
.json-tool-menu-item .menu-icon-wrapper svg {
fill: #222;
}
.json-tool-menu-item .menu-text {
color: rgb(96, 126, 252);
font-weight: bold;
}
.json-tool-menu-item.selected .menu-text,
.json-tool-menu-item.selected .menu-icon-wrapper svg,
.json-tool-menu-item.active .menu-text,
.json-tool-menu-item.active .menu-icon-wrapper svg {
color: #fff !important;
fill: #fff !important;
}
.json-tool-menu-item.selected .menu-icon-wrapper,
.json-tool-menu-item.active .menu-icon-wrapper {
background: #f5f6fa !important;
}
.json-tool-menu-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
user-select: none;
margin-top: 8px;
margin-bottom: 8px;
background: transparent !important;
border-radius: 12px;
transition: background 0.2s;
}
.json-tool-menu-item.selected,
.json-tool-menu-item.active {
background: #fff !important;
}
.json-tool-menu-item .menu-icon-wrapper {
display: inline-flex !important;
align-items: center;
justify-content: center;
width: 40px !important;
height: 40px !important;
min-width: 40px !important;
min-height: 40px !important;
border-radius: 50% !important;
background: #f5f6fa;
margin: 0 auto 4px auto;
transition: background 0.2s;
box-sizing: border-box;
overflow: visible !important;
}
.json-tool-menu-item .menu-icon-wrapper svg {
width: 24px;
height: 24px;
display: block;
fill: #222;
transition: fill 0.2s;
}
.json-tool-menu-item .menu-text {
color: #222;
font-size: 14px;
text-align: center;
transition: color 0.2s;
}
.json-tool-menu-item.selected .menu-icon-wrapper,
.json-tool-menu-item.active .menu-icon-wrapper {
background: rgb(96, 126, 252) !important;
}
.json-tool-menu-item.selected .menu-icon-wrapper svg,
.json-tool-menu-item.active .menu-icon-wrapper svg {
fill: #fff !important;
}
.json-tool-menu-item.selected .menu-text,
.json-tool-menu-item.active .menu-text {
color: rgb(96, 126, 252) !important;
}
.json-tool-menu-item:hover .menu-icon-wrapper {
background: #e6eaff;
}
.json-tool-menu-item:hover .menu-icon-wrapper svg {
fill: rgb(96, 126, 252);
}
.json-tool-menu-item:hover .menu-text {
color: rgb(96, 126, 252);
}
/* 新增:工具页面淡入动画 */
#json-tool-page {
opacity: 0;
transform: scale(0.98);
transition: opacity 0.4s cubic-bezier(0.32, 0.72, 0, 1), transform 0.4s cubic-bezier(0.32, 0.72, 0, 1);
}
#json-tool-page.show-anim {
opacity: 1;
transform: scale(1);
}
`);
// 缓存相关常量
const IFRAME_URL = 'https://123.musejie.top/';
// 获取iframe内容(去除缓存逻辑,直接返回原始URL)
function getIframeSrcUrl() {
return IFRAME_URL;
}
// 工具页面渲染到主内容区
async function showJsonToolPage() {
const layout = document.querySelector('.ant-layout.site-layout');
if (!layout) return;
// 只隐藏主内容区(如.ant-layout-content),不隐藏菜单栏
const nativeContent = layout.querySelector('.ant-layout-content');
if (nativeContent) nativeContent.style.display = 'none';
// 移除已有的工具页面
const old = document.getElementById('json-tool-page');
if (old) old.remove();
// 创建工具页面容器
const page = document.createElement('div');
page.id = 'json-tool-page';
page.style.width = '100%';
page.style.height = '100%';
page.style.background = '#fff';
page.style.display = 'flex';
page.style.flexDirection = 'column';
// 获取iframe src
const iframeSrc = getIframeSrcUrl();
page.innerHTML = `
<iframe src="${iframeSrc}" style="width:100%;height:100%;border:none;"></iframe>
`;
layout.appendChild(page);
// 动画:先不透明度0,下一帧加class
requestAnimationFrame(() => {
page.classList.add('show-anim');
});
}
// 移除工具页面并恢复原生内容
function removeJsonToolPage() {
const layout = document.querySelector('.ant-layout.site-layout');
if (!layout) return;
// 恢复主内容区显示
const nativeContent = layout.querySelector('.ant-layout-content');
if (nativeContent) nativeContent.style.display = '';
// 移除工具页面
const old = document.getElementById('json-tool-page');
if (old) old.remove();
}
// 插入菜单按钮
function insertMenuButton() {
const menuLists = document.querySelectorAll('.ant-menu.ant-menu-root.ant-menu-inline.ant-menu-light.side-menu');
let menuList = null;
menuLists.forEach(ul => {
if (!ul.classList.contains('bottom-menu')) menuList = ul;
});
if (!menuList) return;
if (menuList.querySelector('.json-tool-menu-item')) return;
const li = document.createElement('li');
li.className = 'ant-menu-item ant-menu-item-only-child json-tool-menu-item';
li.setAttribute('role', 'menuitem');
li.style.paddingLeft = '24px';
li.innerHTML = `
<span class="ant-menu-title-content">
<a class="menu-item" href="javascript:void(0)">
<div class="menu-icon-wrapper">
<svg viewBox="0 0 1024 1024">
<path d="M406.409701 486.995257h-332.769427a63.994121 63.994121 0 0 1-63.99412-67.193826V86.392063a63.994121 63.994121 0 0 1 63.99412-63.994121h332.769427a63.994121 63.994121 0 0 1 67.193827 63.994121v333.409368a63.994121 63.994121 0 0 1-67.193827 67.193826z m0-400.603194H76.83998l3.839648 330.209662h325.730073z m0 330.209662zM767.976482 503.633729a63.994121 63.994121 0 0 1-46.715708-19.198237L536.317766 299.492484a63.994121 63.994121 0 0 1 0-92.791475L720.620833 21.758001a63.994121 63.994121 0 0 1 92.791475 0l184.303067 184.943008a63.994121 63.994121 0 0 1 0 92.791475l-184.303067 184.943008a63.994121 63.994121 0 0 1-45.435826 19.198237zM589.432886 255.976482L767.976482 431.320372 945.240196 255.976482 767.976482 74.873121zM406.409701 1023.905929h-332.769427a63.994121 63.994121 0 0 1-63.99412-67.193827V620.742969a63.994121 63.994121 0 0 1 63.99412-63.99412h332.769427a63.994121 63.994121 0 0 1 67.193827 63.99412v333.409368A63.994121 63.994121 0 0 1 406.409701 1023.905929z m0-400.603195l-329.569721 3.199706 3.839648 330.209662 325.730073-3.199706z m0 330.209662zM933.721254 1023.905929H600.311886a63.994121 63.994121 0 0 1-63.99412-67.193827V620.742969a63.994121 63.994121 0 0 1 63.99412-63.99412h333.409368a63.994121 63.994121 0 0 1 63.994121 63.99412v333.409368a63.994121 63.994121 0 0 1-63.994121 69.753592z m-3.839647-403.16296l-329.569721 3.199706 3.839648 330.209662 325.730073-3.199706z m3.839647 330.209662z"/>
</svg>
</div>
<div class="menu-text">秒链工具</div>
</a>
</span>
`;
// 点击“秒链工具”按钮
li.addEventListener('click', function(e) {
document.querySelectorAll('.json-tool-menu-item').forEach(item => item.classList.remove('selected', 'active'));
li.classList.add('selected');
showJsonToolPage();
});
menuList.appendChild(li);
// 给所有原生菜单按钮添加点击事件
menuList.querySelectorAll('.ant-menu-item:not(.json-tool-menu-item)').forEach(item => {
item.addEventListener('click', function() {
removeJsonToolPage();
document.querySelectorAll('.json-tool-menu-item.selected').forEach(btn => btn.classList.remove('selected'));
});
});
}
// 监听菜单切换,移除工具页面
function observeMenu() {
insertMenuButton();
const observer = new MutationObserver(() => {
insertMenuButton();
// 如果“秒链工具”未被选中,移除工具页面
const selected = document.querySelector('.json-tool-menu-item.selected');
if (!selected) removeJsonToolPage();
});
observer.observe(document.body, { childList: true, subtree: true });
window.addEventListener('hashchange', () => {
insertMenuButton();
const selected = document.querySelector('.json-tool-menu-item.selected');
if (!selected) removeJsonToolPage();
});
window.addEventListener('popstate', () => {
insertMenuButton();
const selected = document.querySelector('.json-tool-menu-item.selected');
if (!selected) removeJsonToolPage();
});
}
// 创建弹窗
function createModal() {
const modal = document.createElement('div');
modal.id = 'json-tool-modal';
modal.innerHTML = `
<div id="json-tool-content">
<div class="json-tool-drag-handle"></div>
<div id="json-tool-header">
<div id="json-tool-title">
<svg viewBox="0 0 24 24">
<path d="M14,11H10V9h4V11z M14,8H10V6h4V8z M20,4V20H4V4H20 M20,2H4C2.9,2,2,2.9,2,4v16c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V4 C22,2.9,21.1,2,20,2L20,2z M16,15H8v-2h8V15z M16,18H8v-2h8V18z M6,15H4v2h2V15z M6,18H4v2h2V18z M6,6H4v8h2V6z"></path>
</svg>
<span>JSON秒传链接工具</span>
</div>
<div id="json-tool-header-btns">
<button id="json-tool-maximize" title="最大化">
<svg viewBox="0 0 24 24">
<path id="json-tool-maximize-icon" d="M3 3h7v2H5v5H3V3zm11 0h7v7h-2V5h-5V3zm7 11v7h-7v-2h5v-5h2zm-11 7H3v-7h2v5h5v2z"/>
</svg>
</button>
<button id="json-tool-close" title="关闭">
<svg viewBox="0 0 24 24">
<path d="M18.3 5.71a1 1 0 0 0-1.41 0L12 10.59 7.11 5.7A1 1 0 0 0 5.7 7.11L10.59 12l-4.89 4.89a1 1 0 1 0 1.41 1.41L12 13.41l4.89 4.89a1 1 0 0 0 1.41-1.41L13.41 12l4.89-4.89a1 1 0 0 0 0-1.4z"/>
</svg>
</button>
</div>
</div>
<iframe id="json-tool-iframe" src="" style="width:100%;height:100%;border:none;"></iframe>
</div>
`;
// 设置iframe src(异步)
const iframe = modal.querySelector('#json-tool-iframe');
if (iframe) iframe.src = getIframeSrcUrl();
modal.querySelector('#json-tool-close').addEventListener('click', hideModal);
modal.addEventListener('click', function(e) {
if (e.target === modal) {
hideModal();
}
});
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
hideModal();
}
});
// 拖拽弹窗功能
let isModalDragging = false;
let modalStartX, modalStartY;
const dragHandle = modal.querySelector('.json-tool-drag-handle');
const content = modal.querySelector('#json-tool-content');
dragHandle.addEventListener('mousedown', startModalDrag);
function startModalDrag(e) {
isModalDragging = true;
modalStartX = e.clientX;
modalStartY = e.clientY;
content.style.transition = 'none';
document.addEventListener('mousemove', onModalDrag);
document.addEventListener('mouseup', stopModalDrag);
}
function onModalDrag(e) {
if (!isModalDragging) return;
const deltaX = e.clientX - modalStartX;
const deltaY = e.clientY - modalStartY;
content.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
}
function stopModalDrag() {
if (!isModalDragging) return;
isModalDragging = false;
content.style.transition = '';
content.style.transform = '';
document.removeEventListener('mousemove', onModalDrag);
document.removeEventListener('mouseup', stopModalDrag);
}
// 最大化/还原功能
const maximizeBtn = modal.querySelector('#json-tool-maximize');
const maximizeIcon = modal.querySelector('#json-tool-maximize-icon');
const contentBox = modal.querySelector('#json-tool-content');
let isMaximized = false;
maximizeBtn.addEventListener('click', function() {
isMaximized = !isMaximized;
if (isMaximized) {
contentBox.style.width = '100vw';
contentBox.style.height = '100vh';
contentBox.style.maxWidth = '100vw';
contentBox.style.maxHeight = '100vh';
contentBox.style.borderRadius = '0';
contentBox.style.top = '0';
contentBox.style.left = '0';
contentBox.style.position = 'fixed';
contentBox.style.zIndex = '10002';
maximizeIcon.innerHTML = '<path d="M7 14H5v5h5v-2H7v-3zm7 3v2h5v-5h-2v3h-3zm3-10V5h-3V3h5v5h-2V7zm-7-2V3H3v5h2V5h3z"/>';
} else {
contentBox.style.width = '';
contentBox.style.height = '';
contentBox.style.maxWidth = '1200px';
contentBox.style.maxHeight = '';
contentBox.style.borderRadius = '16px';
contentBox.style.top = '';
contentBox.style.left = '';
contentBox.style.position = '';
contentBox.style.zIndex = '';
maximizeIcon.innerHTML = '<path d="M3 3h7v2H5v5H3V3zm11 0h7v7h-2V5h-5V3zm7 11v7h-7v-2h5v-5h2zm-11 7H3v-7h2v5h5v2z"/>';
}
});
document.body.appendChild(modal);
return modal;
}
function showModal() {
const modal = document.getElementById('json-tool-modal');
if (modal) {
document.body.style.overflow = 'hidden';
setTimeout(() => {
modal.classList.add('show');
}, 10);
}
}
function hideModal() {
const modal = document.getElementById('json-tool-modal');
if (modal) {
modal.classList.remove('show');
setTimeout(() => {
document.body.style.overflow = '';
}, 300);
}
// 关闭弹窗时取消按钮选中
document.querySelectorAll('.json-tool-menu-item.selected').forEach(item => item.classList.remove('selected'));
}
function init() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
createModal();
observeMenu();
});
} else {
createModal();
observeMenu();
}
}
init();
// 剪贴板代理逻辑保留
window.addEventListener('message', async function(event) {
if (!event.origin.startsWith('https://123.musejie.top')) return;
const { type, text } = event.data || {};
if (type === 'copyToClipboard') {
try {
await navigator.clipboard.writeText(text);
event.source.postMessage({ type: 'copyResult', success: true }, event.origin);
} catch (e) {
event.source.postMessage({ type: 'copyResult', success: false, error: e.message }, event.origin);
}
}
if (type === 'pasteFromClipboard') {
try {
const clipText = await navigator.clipboard.readText();
event.source.postMessage({ type: 'pasteResult', success: true, text: clipText }, event.origin);
} catch (e) {
event.source.postMessage({ type: 'pasteResult', success: false, error: e.message }, event.origin);
}
}
});
})();