JSON Copy Button

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

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==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);
        });
    });
})();