Grok Code Style with Collapse

Shrink, collapse, compact, and download pre/code blocks on Grok pages with manual language switch (fixed selector error)

От 15.03.2025. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Grok Code Style with Collapse
// @namespace    http://tampermonkey.net/
// @version      2.2
// @description  Shrink, collapse, compact, and download pre/code blocks on Grok pages with manual language switch (fixed selector error)
// @author       You
// @match        https://x.com/i/grok*
// @match        https://grok.com/*
// @match        https://grok.x.ai/*
// @match        https://x.ai/*
// @exclude      https://greasyfork.org/*
// @exclude      https://*.org/*
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Language options
    const translations = {
        'en': { expand: 'Expand', collapse: 'Collapse', download: 'Download' }, // English (default)
        'zh-TW': { expand: '展開', collapse: '收起', download: '下載' },       // Traditional Chinese
        'zh-CN': { expand: '展开', collapse: '收起', download: '下载' },       // Simplified Chinese
        'ja': { expand: '展開', collapse: '折り畳む', download: 'ダウンロード' }, // Japanese
        'ko': { expand: '펼치기', collapse: '접기', download: '다운로드' },      // Korean
        'fr': { expand: 'Développer', collapse: 'Réduire', download: 'Télécharger' }, // French
        'es': { expand: 'Expandir', collapse: 'Colapsar', download: 'Descargar' }     // Spanish
    };

    // Load saved language or default to 'en'
    let currentLang = GM_getValue('selectedLang', 'en');
    let lang = translations[currentLang];

    // Register language switch menu in Tampermonkey
    for (let langCode in translations) {
        GM_registerMenuCommand(`Switch to ${langCode.toUpperCase()}`, () => {
            currentLang = langCode;
            GM_setValue('selectedLang', langCode);
            lang = translations[langCode];
            wrapCodeBlocks(); // Reapply with new language
        });
    }

    // Add styles (from 1.5)
    GM_addStyle(`
        .grok-code-wrapper {
            position: relative;
            margin: 0;
        }
        .grok-code-wrapper pre, .grok-code-wrapper code {
            max-height: 100px;
            overflow-y: hidden;
            font-size: 10px;
            line-height: 1.1;
            background-color: #f5f5f5;
            padding: 3px;
            border: 1px solid #ddd;
            display: block;
            transition: max-height 0.3s ease;
        }
        .grok-code-wrapper.expanded pre, .grok-code-wrapper.expanded code {
            max-height: 300px;
            overflow-y: auto;
        }
        .grok-toggle-btn {
            position: absolute;
            top: 2px;
            right: 2px;
            font-size: 10px;
            padding: 1px 4px;
            cursor: pointer;
            background: #ddd;
            border: none;
            border-radius: 2px;
        }
        .grok-download-btn {
            position: absolute;
            top: 2px;
            right: 40px;
            font-size: 9px;
            padding: 1px 4px;
            cursor: pointer;
            background: #4CAF50;
            color: white;
            border: none;
            border-radius: 2px;
        }
        .grok-download-btn:hover {
            background: #45a049;
        }
    `);

    // Process code blocks (fixed selector)
    function wrapCodeBlocks() {
        // Simplified selector to avoid nested :not syntax error
        const codeBlocks = document.querySelectorAll('pre:not([class*="highlight"]):not([id*="highlight"]), code:not([class*="highlight"]):not([id*="highlight"])');
        codeBlocks.forEach((block, index) => {
            const parent = block.parentElement;
            if (!parent.classList.contains('grok-code-wrapper')) {
                const wrapper = document.createElement('div');
                wrapper.className = 'grok-code-wrapper';
                parent.insertBefore(wrapper, block);
                wrapper.appendChild(block);

                const toggleBtn = document.createElement('button');
                toggleBtn.className = 'grok-toggle-btn';
                toggleBtn.textContent = lang.expand;
                wrapper.appendChild(toggleBtn);

                const downloadBtn = document.createElement('button');
                downloadBtn.className = 'grok-download-btn';
                downloadBtn.textContent = lang.download;
                wrapper.appendChild(downloadBtn);

                toggleBtn.addEventListener('click', () => {
                    wrapper.classList.toggle('expanded');
                    toggleBtn.textContent = wrapper.classList.contains('expanded') ? lang.collapse : lang.expand;
                });

                downloadBtn.addEventListener('click', () => {
                    const blob = new Blob([block.textContent], { type: 'text/plain' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `code_block_${index + 1}.txt`;
                    a.click();
                    URL.revokeObjectURL(url);
                });
            } else {
                // Update existing buttons with new language
                const toggleBtn = parent.querySelector('.grok-toggle-btn');
                if (toggleBtn) {
                    toggleBtn.textContent = parent.classList.contains('expanded') ? lang.collapse : lang.expand;
                }
                const downloadBtn = parent.querySelector('.grok-download-btn');
                if (downloadBtn) {
                    downloadBtn.textContent = lang.download;
                }
            }
        });
    }

    // Periodic check (from 1.5)
    wrapCodeBlocks();
    setInterval(wrapCodeBlocks, 2000);
})();