JSON Copy Button

为类似demo.html结构的页面添加JSON复制按钮

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         JSON Copy Button
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  为类似demo.html结构的页面添加JSON复制按钮
// @author       Trae AI
// @match        *://*/*
// @grant        GM_addStyle
// @grant        GM.addStyle
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 添加按钮样式
    GM_addStyle(`
        .json-copy-btn {
            position: absolute;
            top: 10px;
            left: 10px;
            padding: 4px 8px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            z-index: 10000;
        }
        .json-copy-btn:hover {
            background-color: #45a049;
        }
    `);

    // 检查页面是否包含类似结构
    function checkForJsonStructure() {
        const nodes = document.querySelectorAll('.vjs-tree:not([data-copy-button-added])') || [];
        console.log('检查页面JSON结构:', nodes.length > 0 ? '找到新的结构' : '未找到新的结构');
        return nodes;
    }

    // 创建复制按钮
    function createCopyButton(container) {
        console.log('创建复制按钮...');
        const button = document.createElement('button');
        button.className = 'json-copy-btn';
        button.textContent = '复制JSON';
        button.onclick = async () => {
            const jsonContent = extractJsonContent(container);
            try {
                await navigator.clipboard.writeText(jsonContent);
                console.log('JSON内容复制成功');
                button.textContent = '复制成功!';
                setTimeout(() => {
                    button.textContent = '复制JSON';
                }, 2000);
            } catch (err) {
                button.textContent = '复制失败';
                console.error('JSON内容复制失败:', err);
            }
        };
        container.style.position = 'relative';
        container.appendChild(button);
        container.setAttribute('data-copy-button-added', 'true');
    }

    // 提取JSON内容
    function extractJsonContent(container) {
        console.log('开始提取JSON内容...');
        const jsonObj = {};
        const nodes = container.querySelectorAll('.vjs-tree__node');
        
        nodes.forEach(node => {
            const key = node.querySelector('.vjs-key');
            const value = node.querySelector('.vjs-value');
            
            if (key && value) {
                const keyText = key.textContent.replace(':', '');
                let valueText = '';
                
                if (value.classList.contains('vjs-value__string')) {
                    valueText = value.textContent.replace(/^"(.*)"$/, '$1');
                } else if (value.classList.contains('vjs-value__number')) {
                    valueText = Number(value.textContent);
                } else if (value.textContent === '[') {
                    valueText = [];
                    // 处理数组内容
                    let nextNode = node.nextElementSibling;
                    while (nextNode && !nextNode.textContent.includes(']')) {
                        const arrayValue = nextNode.querySelector('.vjs-value');
                        if (arrayValue) {
                            valueText.push(arrayValue.textContent.replace(/^"(.*)"$/, '$1'));
                        }
                        nextNode = nextNode.nextElementSibling;
                    }
                }
                
                if (keyText && valueText !== '') {
                    jsonObj[keyText] = valueText;
                }
            }
        });
        
        const result = JSON.stringify(jsonObj, null, 2);
        console.log('JSON内容提取完成:', result);
        return result;
    }

    // 创建 MutationObserver 实例
    const observer = new MutationObserver((mutations) => {
        console.log('检测到 DOM 变化,正在检查 JSON 结构...');
        const newStructures = checkForJsonStructure();
        newStructures.forEach(structure => {
            console.log('发现新的 JSON 结构,添加复制按钮...');
            createCopyButton(structure);
        });
    });

    // 配置 observer
    const config = {
        childList: true,
        subtree: true
    };

    // 开始观察
    window.addEventListener('load', () => {
        console.log('页面加载完成,开始监听 DOM 变化...');
        observer.observe(document.body, config);
        
        // 初始检查
        const initialStructures = checkForJsonStructure();
        initialStructures.forEach(structure => {
            console.log('页面加载完成时发现 JSON 结构,添加复制按钮...');
            createCopyButton(structure);
        });
    });
})();