Golang Playground ACE editor

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

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==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
// @match        https://play.golang.org/
// @match        https://play.golang.org/p/*
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @license      GPL-3.0
// @supportURL   https://codeberg.org/masoudd/Golang_Playground_ACE_editor
// @copyright    2020, masoudd (https://greasyfork.org/en/users/506611-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;
}
`);
})();