NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Golang Playground ACE editor // @namespace http://masoudd.ir/ // @version 0.5.1 // @description Make golang play editor usable. With format and theme support. // @author masoud_dot_naservand on google's email // @author TadeuszMW tadeuszmw gmail.com // @match https://play.golang.org/ // @match https://play.golang.org/p/* // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @license GPL-3.0-or-later // @copyright 2020, masoudd (https://openuserjs.org/users/masoudd) // @copyright 2018, Teeed (https://openuserjs.org/users/Teeed) // ==/UserScript== /* 0.5.1: - Fix the things play.golang.org broke 0.5: - Devided themes to Bright and Dark groups - Changed default theme to solarized_light so it looks like the default go playground theme 0.4: - Updated the ace.js from 1.3.3 to 1.4.9 - Format button now functions - Added theme support 0.3: Also applies to code posted on playground. 0.2: Ctrl + Enter executes script. */ (function() { 'use strict'; var themes = {"Bright": ["chrome", "clouds", "crimson_editor", "dawn", "dreamweaver", "eclipse", "github", "iplastic", "solarized_light", "textmate", "tomorrow", "xcode", "kuroir", "katzenmilch", "sqlserver"], "Dark" : ["ambiance", "chaos", "clouds_midnight", "cobalt","dracula", "gob", "gruvbox", "idle_fingers", "kr_theme", "merbivore", "merbivore_soft", "mono_industrial", "monokai", "nord_dark", "pastel_on_dark", "solarized_dark", "terminal", "tomorrow_night", "tomorrow_night_blue", "tomorrow_night_bright", "tomorrow_night_eighties","twilight", "vibrant_ink"], }; var scrpt = document.createElement('script'); scrpt.src = 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.9/ace.min.js' scrpt.type = 'text/javascript'; scrpt.async = true; scrpt.onload = function() { // need to set basePath because ace.js can't find it in it's own if we are // loading it as ace.min.js ace.config.set("basePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.9"); var wrap = document.getElementById("wrap") var linedTextarea = document.querySelector(".linedtextarea"); linedTextarea.style.display = 'none' var codeArea = document.getElementById("code"); var currentCode = codeArea.value; var editorDiv = document.createElement('div') editorDiv.id = "newNiceEditorDiv" editorDiv.style.width = '100%' editorDiv.style.height = '100%' wrap.appendChild(editorDiv); var editor = ace.edit("newNiceEditorDiv"); editor.session.setValue(currentCode); editor.session.on('change', function(){ codeArea.value = editor.session.getValue(); }); // need to intercept the call to .val on the textArea // in ajax callback for format button to update the contents // of editor by the formatted code returned const originalVal = $.fn.val; $.fn.val = function(x) { if (this[0].id === 'code' && x) { editor.session.setValue(x); } return originalVal.apply(this, arguments); }; var savedTheme = GM_getValue('theme', false); if (!savedTheme) { savedTheme = 'solarized_light'; GM_setValue('theme', savedTheme); } var themeLabel = document.createElement('label'); themeLabel.setAttribute('title', 'Theme'); var select = document.createElement('select'); select.setAttribute('id', 'themeSelect'); for (var group in themes) { var optGroup = document.createElement('optgroup'); optGroup.setAttribute('label', group); themes[group].forEach(function(theme) { var opt = document.createElement('option'); opt.setAttribute('value', theme); if (theme === savedTheme) { opt.setAttribute('selected', 'true'); } opt.text = theme.replace(/_/g, ' '); optGroup.appendChild(opt); }); select.appendChild(optGroup); } themeLabel.appendChild(select); document.getElementById('aboutButton').before(themeLabel); select.addEventListener('change', function(e) { editor.setTheme(`ace/theme/${this.value}`); GM_setValue('theme', this.value); }); // observe the editorDiv element for class attribute change, to catch // when the new themes apply and set the color and background-color // for #output const observeConf = { attributes: true, attributeFilter: ['class'], }; // the closure const observer = new MutationObserver(function(mlist, obs) { var color = ''; var backgroundColor = ''; const output = document.getElementById('output'); return function(mlist, obs) { var cs = getComputedStyle(editorDiv); if (color !== cs.color || backgroundColor !== cs.backgroundColor) { color = cs.color; backgroundColor = cs.backgroundColor; output.setAttribute('style', `color: ${color}; background-color: ${backgroundColor}`); } } }()); observer.observe(editorDiv, observeConf); editor.setTheme(`ace/theme/${savedTheme}`); editor.session.setMode("ace/mode/golang"); editorDiv.style.fontSize='16px'; function doSubmit() { document.getElementById('run').click() } window.addEventListener("keypress", function(e) { if(e.ctrlKey && e.key == 'Enter') { doSubmit() } }, false); } document.head.appendChild(scrpt); GM_addStyle ( ` #wrap { padding: 0; background: none; } select { height: 30px; border: 1px solid #375EAB; font-size: 16px; font-family: sans-serif; background: #375EAB; color: white; position: static; top: 1px; border-radius: 5px; padding-left: 1em; } `); })();