GreasyFork Code: Syntax Highlight by CodeMirror

To syntax hightlight GreasyFork Code by CodeMirror

目前为 2023-07-30 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name GreasyFork Code: Syntax Highlight by CodeMirror
  3. // @namespace Violentmonkey Scripts
  4. // @match https://greasyfork.org/*
  5. // @grant none
  6. // @version 0.1.0
  7. // @author CY Fung
  8. // @description To syntax hightlight GreasyFork Code by CodeMirror
  9. // @run-at document-start
  10. // @inject-into page
  11. // @unwrap
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (() => {
  16. let byPass = true;
  17.  
  18. let documentReady = new Promise(resolve => {
  19. Promise.resolve().then(() => {
  20. if (document.readyState !== 'loading') {
  21. resolve();
  22. } else {
  23. window.addEventListener("DOMContentLoaded", resolve, false);
  24. }
  25. });
  26. });
  27.  
  28. // Function to load CodeMirror library
  29. function loadCodeMirror(arr) {
  30.  
  31.  
  32. const promises = arr.map((href) => {
  33. return new Promise(resolve => {
  34.  
  35.  
  36. const script = document.createElement('script');
  37. script.src = href;
  38. script.onload = () => {
  39. resolve(script);
  40. };
  41. document.head.appendChild(script);
  42.  
  43. });
  44.  
  45.  
  46. });
  47.  
  48. return Promise.all(promises);
  49. }
  50.  
  51. // Function to load CodeMirror CSS
  52. function loadCodeMirrorCSS(href) {
  53. const link = document.createElement('link');
  54. link.rel = 'stylesheet';
  55. link.href = href;
  56. document.head.appendChild(link);
  57. }
  58.  
  59. async function runBlock(codeBlock){
  60.  
  61. let textarea = document.createElement('textarea');
  62. textarea.value = `${codeBlock.textContent}`;
  63. textarea.readOnly = true;
  64. textarea.id = 'editor651';
  65.  
  66. textarea.style.width = '100%';
  67. textarea.style.height = '400px';
  68.  
  69. codeBlock.replaceWith(textarea);
  70. codeBlock.remove();
  71.  
  72. await Promise.resolve();
  73. await new Promise(r=>setTimeout(r, 20));
  74.  
  75.  
  76.  
  77.  
  78. let editor651 = CodeMirror.fromTextArea(document.querySelector('#editor651'), {
  79.  
  80. mode: "javascript",
  81.  
  82. readOnly: true,
  83. styleActiveLine: true,
  84. lineNumbers: true,
  85. });
  86. editor651.save();
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94. }
  95.  
  96. // Main function to apply CodeMirror syntax highlighting to pre elements
  97. function applyCodeMirrorSyntaxHighlighting() {
  98. const codeBlocks = document.querySelectorAll('pre.prettyprint.linenums.lang-js');
  99.  
  100.  
  101. // Check if CodeMirror is loaded
  102. if (typeof CodeMirror !== 'undefined') {
  103.  
  104. codeBlocks.forEach(runBlock);
  105. } else {
  106. console.error('CodeMirror library is not loaded. Syntax highlighting cannot be applied.');
  107. }
  108. }
  109.  
  110. async function doAction() {
  111.  
  112.  
  113. await new Promise(r => setTimeout(r, 0));
  114.  
  115. if (mgg) {
  116.  
  117. byPass = false;
  118.  
  119.  
  120. document.head.appendChild(document.createElement('style')).textContent = `
  121.  
  122. body {
  123.  
  124. display: flex;
  125. flex-direction: column;
  126. height: 100vh;
  127. }
  128.  
  129. body > div:last-child{
  130. height:0;
  131. flex-grow:1;
  132. display: flex;
  133. flex-direction:column;
  134. }
  135.  
  136. body > div:last-child > #script-info:last-child{
  137.  
  138. height:0;
  139. flex-grow:1;
  140. display: flex;
  141. flex-direction:column;
  142.  
  143. }
  144.  
  145. body > div:last-child > #script-info:last-child > #script-content:last-child{
  146.  
  147.  
  148. height:0;
  149. flex-grow:1;
  150. display: flex;
  151. flex-direction:column;
  152. }
  153.  
  154. body > div:last-child > #script-info:last-child > #script-content:last-child > .code-container:last-child{
  155.  
  156.  
  157. height:0;
  158. flex-grow:1;
  159. display: flex;
  160. flex-direction:column;
  161.  
  162. }
  163.  
  164. body > div:last-child > #script-info:last-child > #script-content:last-child > .code-container:last-child > textarea:last-child{
  165.  
  166.  
  167. height:0;
  168. flex-grow:1;
  169. display: flex;
  170. flex-direction:column;
  171.  
  172. }
  173.  
  174. body > div:last-child > #script-info:last-child > #script-content:last-child > .code-container:last-child > .CodeMirror:last-child{
  175.  
  176.  
  177. height:0;
  178. flex-grow:1;
  179. display: flex;
  180. flex-direction:column;
  181.  
  182. }
  183.  
  184. `;
  185.  
  186. await loadCodeMirror(['https://cdn.jsdelivr.net/npm/codemirror@5.65.14/lib/codemirror.min.js']);
  187.  
  188. await loadCodeMirror([
  189. 'https://cdn.jsdelivr.net/npm/codemirror@5.65.14/mode/javascript/javascript.min.js',
  190. 'https://cdn.jsdelivr.net/npm/codemirror@5.65.14/addon/selection/active-line.min.js']);
  191.  
  192. loadCodeMirrorCSS('https://cdn.jsdelivr.net/npm/codemirror@5.65.14/lib/codemirror.min.css');
  193.  
  194. await new Promise(r => setTimeout(r, 0));
  195.  
  196.  
  197. applyCodeMirrorSyntaxHighlighting();
  198.  
  199.  
  200.  
  201.  
  202. }
  203.  
  204.  
  205.  
  206. }
  207.  
  208.  
  209. let mz = HTMLElement.prototype.getElementsByTagName
  210. let mzd = Document.prototype.getElementsByTagName
  211.  
  212. let mgg = 0;
  213. async function mTz() {
  214. if (mgg) return;
  215. mgg = 1;
  216. byPass = false;
  217. documentReady.then(doAction);
  218. }
  219.  
  220. function getElementsByTagName(tag) {
  221.  
  222. if (tag === 'pre' || tag === 'code' || tag === 'xmp') {
  223. if (byPass) {
  224. setTimeout(mTz, 10)
  225. return [];
  226. }
  227. }
  228. if (this instanceof Document) {
  229. return mzd.call(this, tag);
  230. } else {
  231. return mz.call(this, tag);
  232. }
  233. }
  234.  
  235.  
  236. HTMLElement.prototype.getElementsByTagName = getElementsByTagName
  237. Document.prototype.getElementsByTagName = getElementsByTagName
  238.  
  239. /*
  240. let mz= function(evt){
  241.  
  242. if(evt && evt.type ==='readystatechange') return;
  243. return EventTarget.prototype.addEventListener.apply(this,arguments)
  244.  
  245. };
  246. window.addEventListener = mz
  247. document.addEventListener = mz;
  248. */
  249.  
  250.  
  251.  
  252. })();
  253.  
  254.  
  255.  
  256.