Golang Playground ACE editor

Make golang play editor usable. With format and theme support.

当前为 2020-04-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Golang Playground ACE editor
  3. // @namespace http://masoudd.ir/
  4. // @version 0.4
  5. // @description Make golang play editor usable. With format and theme support.
  6. // @author TadeuszMW tadeuszmw gmail.com
  7. // @match https://play.golang.org/
  8. // @match https://play.golang.org/p/*
  9. // @grant GM_addStyle
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @license GPL-3.0
  13. // @supportURL https://codeberg.org/masoudd/Golang_Playground_ACE_editor
  14. // @copyright 2018, Teeed (https://openuserjs.org/users/Teeed)
  15. // @copyright 2020, masoudd (https://greasyfork.org/en/users/506611-masoudd)
  16. // ==/UserScript==
  17.  
  18. /*
  19. 0.4:
  20. - Updated the ace.js from 1.3.3 to 1.4.9
  21. - Format button now functions
  22. - Added theme support
  23.  
  24. 0.3:
  25. Also applies to code posted on playground.
  26.  
  27. 0.2:
  28. Ctrl + Enter executes script.
  29. */
  30.  
  31. (function() {
  32. 'use strict';
  33. var themes = ["ambiance", "chaos", "chrome", "clouds", "clouds_midnight", "cobalt",
  34. "crimson_editor", "dawn", "dracula", "dreamweaver", "eclipse", "github",
  35. "gob", "gruvbox", "idle_fingers", "iplastic", "katzenmilch", "kr_theme",
  36. "kuroir", "merbivore", "merbivore_soft", "mono_industrial", "monokai",
  37. "nord_dark", "pastel_on_dark", "solarized_dark", "solarized_light",
  38. "sqlserver", "terminal", "textmate", "tomorrow", "tomorrow_night",
  39. "tomorrow_night_blue", "tomorrow_night_bright", "tomorrow_night_eighties",
  40. "twilight", "vibrant_ink", "xcode"];
  41. var scrpt = document.createElement('script');
  42. scrpt.src = 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.9/ace.min.js'
  43. scrpt.type = 'text/javascript';
  44. scrpt.async = true;
  45. scrpt.onload = function() {
  46. // need to set basePath because ace.js can't find it in it's own if we are
  47. // loading it as ace.min.js
  48. ace.config.set("basePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.9");
  49. var wrap = document.getElementById("wrap")
  50.  
  51. var linedTextarea = document.querySelector(".linedtextarea");
  52. linedTextarea.style.display = 'none'
  53.  
  54. var codeArea = document.getElementById("code");
  55. var currentCode = codeArea.value;
  56.  
  57. var editorDiv = document.createElement('div')
  58. editorDiv.id = "newNiceEditorDiv"
  59. editorDiv.style.width = '100%'
  60. editorDiv.style.height = '100%'
  61. wrap.appendChild(editorDiv);
  62.  
  63. var editor = ace.edit("newNiceEditorDiv");
  64. editor.session.setValue(currentCode);
  65. editor.session.on('change', function(){
  66. codeArea.value = editor.session.getValue();
  67. });
  68.  
  69. // need to intercept the call to .val on the textArea
  70. // in ajax callback for format button to update the contents
  71. // of editor by the formatted code returned
  72. const originalVal = $.fn.val;
  73. $.fn.val = function(x) {
  74. if (this[0].id === 'code' && x) {
  75. editor.session.setValue(x);
  76. }
  77. return originalVal.apply(this, arguments);
  78. };
  79.  
  80. var savedTheme = GM_getValue('theme', false);
  81. if (!savedTheme) {
  82. savedTheme = 'ambiance';
  83. GM_setValue('theme', savedTheme);
  84. }
  85. var themeLabel = document.createElement('label');
  86. themeLabel.setAttribute('title', 'Theme');
  87. var select = document.createElement('select');
  88. select.setAttribute('id', 'themeSelect');
  89. themes.forEach(function(theme) {
  90. var opt = document.createElement('option');
  91. opt.setAttribute('value', theme);
  92. if (theme === savedTheme) {
  93. opt.setAttribute('selected', 'true');
  94. }
  95. opt.text = theme.replace(/_/g, ' ');
  96. select.appendChild(opt);
  97. });
  98. themeLabel.appendChild(select);
  99. document.getElementById('controls').appendChild(themeLabel);
  100. select.addEventListener('change', function(e) {
  101. editor.setTheme(`ace/theme/${this.value}`);
  102. GM_setValue('theme', this.value);
  103. });
  104. // observe the editorDiv element for class attribute change, to catch
  105. // when the new themes apply and set the color and background-color
  106. // for #output
  107. const observeConf = {
  108. attributes: true,
  109. attributeFilter: ['class'],
  110. };
  111. // the closure
  112. const observer = new MutationObserver(function(mlist, obs) {
  113. var color = '';
  114. var backgroundColor = '';
  115. const output = document.getElementById('output');
  116. return function(mlist, obs) {
  117. var cs = getComputedStyle(editorDiv);
  118. if (color !== cs.color || backgroundColor !== cs.backgroundColor) {
  119. color = cs.color;
  120. backgroundColor = cs.backgroundColor;
  121. output.setAttribute('style', `color: ${color}; background-color: ${backgroundColor}`);
  122. }
  123. }
  124. }());
  125. observer.observe(editorDiv, observeConf);
  126.  
  127.  
  128.  
  129. editor.setTheme(`ace/theme/${savedTheme}`);
  130. editor.session.setMode("ace/mode/golang");
  131.  
  132. editorDiv.style.fontSize='16px';
  133.  
  134. function doSubmit() {
  135. document.getElementById('run').click()
  136. }
  137.  
  138. window.addEventListener("keypress", function(e) {
  139. if(e.ctrlKey && e.key == 'Enter') {
  140. doSubmit()
  141. }
  142. }, false);
  143.  
  144. }
  145. document.head.appendChild(scrpt);
  146.  
  147.  
  148.  
  149. GM_addStyle ( `
  150. #wrap {
  151. padding: 0;
  152. background: none;
  153. }
  154. select {
  155. height: 30px;
  156. border: 1px solid #375EAB;
  157. font-size: 16px;
  158. font-family: sans-serif;
  159. background: #375EAB;
  160. color: white;
  161. position: static;
  162. top: 1px;
  163. border-radius: 5px;
  164. padding-left: 1em;
  165. }
  166. `);
  167. })();