您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tio.run with Monaco Editor.
// ==UserScript== // @name Tio.run Monaco Editor // @namespace https://greasyfork.org/en/scripts/432456-tio-run-monaco-editor // @version 0.3 // @description Tio.run with Monaco Editor. // @author cgiosy // @match https://tio.run/* // @run-at document-body // ==/UserScript== 'use strict'; let mainExecuted = false; const main = () => { if (mainExecuted) return; mainExecuted = true; const head = document.getElementsByTagName('head')[0]; const monacoStylesheet = document.createElement('style'); monacoStylesheet.textContent = ` * { cursor: inherit; } .monaco-editor .inputarea { background: none; } `; head.appendChild(monacoStylesheet); const monacoLoaderScript = document.createElement('script'); monacoLoaderScript.defer = 'true'; monacoLoaderScript.src = 'https://cdn.jsdelivr.net/npm/[email protected]/min/vs/loader.js'; monacoLoaderScript.onload = () => { const getLanguage = (languageId) => { const languages = ['abap', 'aes', 'apex', 'azcli', 'bat', 'bicep', 'c', 'cameligo', 'clojure', 'coffeescript', 'cpp', 'csharp', 'csp', 'css', 'dart', 'dockerfile', 'ecl', 'elixir', 'fsharp', 'go', 'graphql', 'handlebars', 'hcl', 'html', 'ini', 'java', 'javascript', 'json', 'julia', 'kotlin', 'less', 'lexon', 'liquid', 'lua', 'm3', 'markdown', 'mips', 'msdax', 'mysql', 'objective-c', 'pascal', 'pascaligo', 'perl', 'pgsql', 'php', 'plaintext', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'qsharp', 'r', 'razor', 'redis', 'redshift', 'restructuredtext', 'ruby', 'rust', 'sb', 'scala', 'scheme', 'scss', 'shell', 'sol', 'sparql', 'sql', 'st', 'swift', 'systemverilog', 'tcl', 'twig', 'typescript', 'vb', 'verilog', 'xml', 'yaml']; let max = 0, lang = 'cpp'; if (!languageId) return lang; for (const language of languages) { let common = 0; if (languageId === language) common += 10000000; if (languageId.split('-')[0] === language || languageId.indexOf(language) === 0) common += 1000; for (let i = 0, j = 0; i < languageId.length; i++, j++) { while (j < language.length && languageId[i] !== language[j]) j++; if (j === language.length) break; common++; } if (max < common) { max = common; lang = language; } } return lang; }; const fn = () => { self.MonacoEnvironment = { baseUrl: 'https://cdn.jsdelivr.net/npm/[email protected]/min/' }; importScripts('https://cdn.jsdelivr.net/npm/[email protected]/min/vs/base/worker/workerMain.js'); }; window.MonacoEnvironment = { getWorkerUrl: (workerId, label) => 'data:text/javascript;charset=utf-8,' + encodeURIComponent(`(${fn})()`), }; require.config({ paths: { 'vs': 'https://cdn.jsdelivr.net/npm/[email protected]/min/vs' }}); require(['vs/editor/editor.main'], () => { const prevCodeEditor = document.getElementById('code'); const prevOnInput = prevCodeEditor.oninput; const text = prevCodeEditor.value; const codeEditor = document.createElement('div'); codeEditor.id = 'code'; codeEditor.style = 'width: 100%;'; codeEditor.dataset.mask = 'null'; prevCodeEditor.replaceWith(codeEditor); let prevLanguage = languageId; const monacoEditor = monaco.editor.create(codeEditor, { value: text, language: getLanguage(prevLanguage), insertSpaces: false, tabSize: 4, automaticLayout: true, wordWrap: 'on', minimap: { enabled: false, }, scrollbar: { vertical: 'hidden', horizontal: 'hidden', handleMouseWheel: false, }, scrollBeyondLastLine: false, hideCursorInOverviewRuler: true, overviewRulerBorder: false, overviewRulerLanes: 0, }); Object.defineProperty(codeEditor, 'value', { get: () => monacoEditor.getValue(), set: (value) => monacoEditor.setValue(value), }); monacoEditor.onDidContentSizeChange(() => { codeEditor.style.height = monacoEditor.getContentHeight() + 'px'; monacoEditor.layout(); }); const monacoEditorModel = monacoEditor.getModel(); codeEditor.oninput = (() => { prevOnInput(); if (prevLanguage === languageId) return; monaco.editor.setModelLanguage(monacoEditorModel, getLanguage(languageId)); prevLanguage = languageId; }); monacoEditorModel.onDidChangeContent(codeEditor.oninput); window.removeEventListener("beforeunload", saveState); byteStringToTextArea = (byteString, textArea) => { textArea.value = byteStringToText(byteString); if (textArea !== codeEditor) resize(textArea); }; saveState = (saveIfEmpty) => { if (!languageId) return; var stateString = languageId; var saveTextArea = function(textArea) { if (textArea.readOnly) return; stateString += fieldSeparator + textToByteString(textArea.value); } iterate($$("#interpreter > textarea, #code, #interpreter > :not([data-mask]) textarea"), saveTextArea); iterate($$("#interpreter > [data-mask=false]"), function(element) { if ($("textarea", element) === null) return; stateString += startOfExtraFields + (element.dataset.if || element.dataset.ifNot); iterate($$("textarea", element), saveTextArea); }); var settings = getSettings(); if (settings != "/") stateString += startOfSettings + settings.slice(1,-1); if (saveIfEmpty || ! rEmptyStateString.test(stateString)) history.replaceState({}, "", "##" + byteStringToBase64(byteArrayToByteString(deflate(stateString)))); }; window.addEventListener("beforeunload", saveState); }); const keyPressed = {}; window.addEventListener('keyup', (e) => { keyPressed[e.key.toLowerCase()] = false; }); window.addEventListener('keydown', (e) => { keyPressed[e.key.toLowerCase()] = true; if (keyPressed['control'] === true && keyPressed['s'] === true) { e.preventDefault(); saveState(); document.getElementById('run').click(); } }); }; head.appendChild(monacoLoaderScript); }; const scripts = [...document.querySelectorAll('script[src^="/static/"]')]; let scriptLoadCount = 0; scripts.forEach((script) => { script.onload = () => ++scriptLoadCount === scripts.length && main(); }); window.onload = () => main();