Grok Code Style with Collapse

Shrink, collapse, compact, and download pre/code blocks on Grok pages with manual language switch and adaptive background

  1. // ==UserScript==
  2. // @name Grok Code Style with Collapse
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.3
  5. // @description Shrink, collapse, compact, and download pre/code blocks on Grok pages with manual language switch and adaptive background
  6. // @author You
  7. // @match https://x.com/i/grok*
  8. // @match https://grok.com/*
  9. // @match https://grok.x.ai/*
  10. // @match https://x.ai/*
  11. // @exclude https://gf.qytechs.cn/*
  12. // @exclude https://*.org/*
  13. // @grant GM_addStyle
  14. // @grant GM_registerMenuCommand
  15. // @grant GM_getValue
  16. // @grant GM_setValue
  17. // @license MIT
  18. // ==/UserScript==
  19.  
  20. (function() {
  21. 'use strict';
  22.  
  23. // Language options
  24. const translations = {
  25. 'en': { expand: 'Expand', collapse: 'Collapse', download: 'Download' },
  26. 'zh-TW': { expand: '展開', collapse: '收起', download: '下載' },
  27. 'zh-CN': { expand: '展开', collapse: '收起', download: '下载' },
  28. 'ja': { expand: '展開', collapse: '折り畳む', download: 'ダウンロード' },
  29. 'ko': { expand: '펼치기', collapse: '접기', download: '다운로드' },
  30. 'fr': { expand: 'Développer', collapse: 'Réduire', download: 'Télécharger' },
  31. 'es': { expand: 'Expandir', collapse: 'Colapsar', download: 'Descargar' }
  32. };
  33.  
  34. // Load saved language or default to 'en'
  35. let currentLang = GM_getValue('selectedLang', 'en');
  36. let lang = translations[currentLang];
  37.  
  38. // Register language switch menu in Tampermonkey
  39. for (let langCode in translations) {
  40. GM_registerMenuCommand(`Switch to ${langCode.toUpperCase()}`, () => {
  41. currentLang = langCode;
  42. GM_setValue('selectedLang', langCode);
  43. lang = translations[langCode];
  44. wrapCodeBlocks();
  45. });
  46. }
  47.  
  48. // Add styles with adaptive background
  49. GM_addStyle(`
  50. .grok-code-wrapper {
  51. position: relative;
  52. margin: 0;
  53. }
  54. .grok-code-wrapper pre, .grok-code-wrapper code {
  55. max-height: 100px;
  56. overflow-y: hidden;
  57. font-size: 10px;
  58. line-height: 1.1;
  59. background-color: inherit; /* Adaptive: inherit from parent or page */
  60. color: inherit; /* Adaptive: inherit text color */
  61. padding: 3px;
  62. border: 1px solid #ddd;
  63. display: block;
  64. transition: max-height 0.3s ease;
  65. }
  66. .grok-code-wrapper.expanded pre, .grok-code-wrapper.expanded code {
  67. max-height: 300px;
  68. overflow-y: auto;
  69. }
  70. .grok-toggle-btn {
  71. position: absolute;
  72. top: 2px;
  73. right: 2px;
  74. font-size: 10px;
  75. padding: 1px 4px;
  76. cursor: pointer;
  77. background: #ddd;
  78. border: none;
  79. border-radius: 2px;
  80. }
  81. .grok-download-btn {
  82. position: absolute;
  83. top: 2px;
  84. right: 40px;
  85. font-size: 9px;
  86. padding: 1px 4px;
  87. cursor: pointer;
  88. background: #4CAF50;
  89. color: white;
  90. border: none;
  91. border-radius: 2px;
  92. }
  93. .grok-download-btn:hover {
  94. background: #45a049;
  95. }
  96. `);
  97.  
  98. // Process code blocks
  99. function wrapCodeBlocks() {
  100. const codeBlocks = document.querySelectorAll('pre:not([class*="highlight"]):not([id*="highlight"]), code:not([class*="highlight"]):not([id*="highlight"])');
  101. codeBlocks.forEach((block, index) => {
  102. const parent = block.parentElement;
  103. if (!parent.classList.contains('grok-code-wrapper')) {
  104. const wrapper = document.createElement('div');
  105. wrapper.className = 'grok-code-wrapper';
  106. parent.insertBefore(wrapper, block);
  107. wrapper.appendChild(block);
  108.  
  109. const toggleBtn = document.createElement('button');
  110. toggleBtn.className = 'grok-toggle-btn';
  111. toggleBtn.textContent = lang.expand;
  112. wrapper.appendChild(toggleBtn);
  113.  
  114. const downloadBtn = document.createElement('button');
  115. downloadBtn.className = 'grok-download-btn';
  116. downloadBtn.textContent = lang.download;
  117. wrapper.appendChild(downloadBtn);
  118.  
  119. toggleBtn.addEventListener('click', () => {
  120. wrapper.classList.toggle('expanded');
  121. toggleBtn.textContent = wrapper.classList.contains('expanded') ? lang.collapse : lang.expand;
  122. });
  123.  
  124. downloadBtn.addEventListener('click', () => {
  125. const blob = new Blob([block.textContent], { type: 'text/plain' });
  126. const url = URL.createObjectURL(blob);
  127. const a = document.createElement('a');
  128. a.href = url;
  129. a.download = `code_block_${index + 1}.txt`;
  130. a.click();
  131. URL.revokeObjectURL(url);
  132. });
  133. } else {
  134. const toggleBtn = parent.querySelector('.grok-toggle-btn');
  135. if (toggleBtn) {
  136. toggleBtn.textContent = parent.classList.contains('expanded') ? lang.collapse : lang.expand;
  137. }
  138. const downloadBtn = parent.querySelector('.grok-download-btn');
  139. if (downloadBtn) {
  140. downloadBtn.textContent = lang.download;
  141. }
  142. }
  143. });
  144. }
  145.  
  146. // Periodic check
  147. wrapCodeBlocks();
  148. setInterval(wrapCodeBlocks, 2000);
  149. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址