JSON Copy Button

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

Ekde 2025/02/08. Vidu La ĝisdata versio.

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