// ==UserScript== // @name Grok Code Style with Collapse // @namespace http://tampermonkey.net/ // @version 1.7 // @description Shrink, collapse, compact, and download pre/code blocks on Grok pages with multi-language support // @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 // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 多語言支援 const translations = { 'en': { expand: 'Expand', collapse: 'Collapse', download: 'Download' }, 'zh-TW': { expand: '展開', collapse: '收起', download: '下載' }, 'zh-CN': { expand: '展开', collapse: '收起', download: '下载' }, 'ja': { expand: '展開', collapse: '折り畳む', download: 'ダウンロード' }, 'ko': { expand: '펼치기', collapse: '접기', download: '다운로드' }, 'fr': { expand: 'Développer', collapse: 'Réduire', download: 'Télécharger' }, 'es': { expand: 'Expandir', collapse: 'Colapsar', download: 'Descargar' } }; const userLang = (navigator.language || 'en').toLowerCase(); const lang = translations[userLang] || translations[userLang.split('-')[0]] || translations['en']; // 添加樣式 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; } `); // 處理代碼塊 function wrapCodeBlocks() { const codeBlocks = document.querySelectorAll(':not([class*="highlight"]:not([id*="highlight"])) > pre, :not([class*="highlight"]:not[id*="highlight"]) > code'); codeBlocks.forEach((block, index) => { if (!block.parentElement.classList.contains('grok-code-wrapper')) { const wrapper = document.createElement('div'); wrapper.className = 'grok-code-wrapper'; block.parentElement.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); }); } }); } // 定時檢查 wrapCodeBlocks(); setInterval(wrapCodeBlocks, 2000); })();