index.html
1 <!doctype HTML> 2 <html> 3 <head> 4 <script> 5 // Set variables 6 7 // Get URL parameters: 8 // `code` contains the code of the file in base64 encoded 9 // `theme` can be "vs" for light theme or "vs-dark" for dark theme 10 // `lang` is the language of the file 11 // `wrap` if the editor is wrapping or not 12 // `minimap` if the minimap is shown 13 // `contextMenu` whether to use the Monaco context menu. The built-in context menu 14 // doesn't work in Peek, so we set this to false and create a custom one 15 16 var theme = ("[[PT_THEME]]" == "dark") ? "vs-dark" : "vs"; 17 var wrap = [[PT_WRAP]]; 18 var minimap = [[PT_MINIMAP]]; 19 var stickyScroll = [[PT_STICKY_SCROLL]]; 20 var fontSize = [[PT_FONT_SIZE]]; 21 22 var lang = "[[PT_LANG]]"; 23 var base64code = "[[PT_CODE]]"; 24 var contextMenu = [[PT_CONTEXTMENU]]; 25 26 var editor; 27 28 // Code taken from https://stackoverflow.com/a/30106551/14774889 29 var code = decodeURIComponent(atob(base64code).split('').map(function (c) { 30 return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); 31 }).join('')); 32 33 function runToggleTextWrapCommand() { 34 wrap = !wrap; 35 editor.updateOptions({ wordWrap: wrap ? 'on' : 'off' }); 36 } 37 38 function runToggleMinimap() { 39 minimap = !minimap; 40 editor.updateOptions({minimap: {enabled: minimap}}); 41 } 42 43 function runCopyCommand() { 44 editor.focus(); 45 document.execCommand('copy'); 46 } 47 48 </script> 49 <!-- Set browser to Edge--> 50 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 51 <!-- Set charset --> 52 <meta charset="utf-8" /> 53 <!-- Title (normally not displayed)--> 54 <title>Previewer for developer Files</title> 55 <style> 56 /* Fits content to window size */ 57 html, body { 58 padding: 0; 59 } 60 61 #container, .monaco-editor { 62 position: fixed; 63 height: 100%; 64 left: 0; 65 top: 0; 66 right: 0; 67 bottom: 0; 68 } 69 70 .overflowingContentWidgets { 71 /*Hides alert box */ 72 display: none !important 73 } 74 </style> 75 </head> 76 77 <body> 78 <!-- Container for the editor --> 79 <div id="container"></div> 80 <!-- Script --> 81 <script src="http://[[PT_URL]]/monacoSRC/min/vs/loader.js"></script> 82 <script src="http://[[PT_URL]]/monacoSpecialLanguages.js" type="module"></script> 83 <script type="module"> 84 import { registerAdditionalLanguages } from 'http://[[PT_URL]]/monacoSpecialLanguages.js'; 85 import { customTokenThemeRules } from 'http://[[PT_URL]]/customTokenThemeRules.js'; 86 require.config({ paths: { vs: 'http://[[PT_URL]]/monacoSRC/min/vs' } }); 87 require(['vs/editor/editor.main'], async function () { 88 await registerAdditionalLanguages(monaco) 89 90 // Creates a theme to handle custom tokens 91 monaco.editor.defineTheme('theme', { 92 base: theme, // Sets the base theme to "vs" or "vs-dark" depending on the user's preference 93 inherit: true, 94 rules: customTokenThemeRules, 95 colors: {} // `colors` is a required attribute 96 }); 97 98 // Creates the editor 99 // For all parameters: https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html 100 editor = monaco.editor.create(document.getElementById('container'), { 101 value: code, // Sets content of the editor 102 language: lang, // Sets language of the code 103 readOnly: true, // Sets to readonly 104 theme: 'theme', // Sets editor theme 105 minimap: { enabled: minimap }, // Controls if minimap is shown 106 lineNumbersMinChars: 3, // Width of the line numbers 107 contextmenu: contextMenu, 108 scrollbar: { 109 // Deactivate shadows 110 shadows: false, 111 112 // Render scrollbar automatically 113 vertical: 'auto', 114 horizontal: 'auto', 115 }, 116 stickyScroll: { enabled: stickyScroll }, 117 fontSize: fontSize, 118 wordWrap: (wrap ? 'on' : 'off') // Word wraps 119 }); 120 window.onresize = () => { 121 editor.layout(); 122 }; 123 124 // Add toggle wrap button to context menu 125 editor.addAction({ 126 id: 'text-wrap', 127 128 label: 'Toggle text wrapping', 129 130 // A precondition for this action. 131 precondition: null, 132 133 // A rule to evaluate on top of the precondition in order to dispatch the keybindings. 134 keybindingContext: null, 135 136 contextMenuGroupId: 'cutcopypaste', 137 138 contextMenuOrder: 100, 139 140 // Method that will be executed when the action is triggered. 141 run: runToggleTextWrapCommand 142 }); 143 144 editor.addAction({ 145 id: 'toggle-minimap', 146 147 label: 'Toggle minimap', 148 149 contextMenuGroupId: 'cutcopypaste', 150 151 contextMenuOrder: 100, 152 153 // Method that will be executed when the action is triggered. 154 run: runToggleMinimap 155 }); 156 157 onContextMenu(); 158 }); 159 160 function onContextMenu() { 161 // Hide context menu items 162 // Code modified from https://stackoverflow.com/questions/48745208/disable-cut-and-copy-in-context-menu-in-monaco-editor/65413517#65413517 163 let menus = require('vs/platform/actions/common/actions').MenuRegistry._menuItems 164 let contextMenuEntry = [...menus].find(entry => entry[0].id == 'EditorContext') 165 let contextMenuLinks = contextMenuEntry[1] 166 167 let removableIds = ['editor.action.clipboardCutAction', 'editor.action.formatDocument', 'editor.action.formatSelection', 'editor.action.quickCommand', 'editor.action.quickOutline', 'editor.action.refactor', 'editor.action.sourceAction', 'editor.action.rename', undefined, 'editor.action.revealDefinition', 'editor.action.revealDeclaration', 'editor.action.goToTypeDefinition', 'editor.action.goToImplementation', 'editor.action.goToReferences', 'editor.action.changeAll'] 168 169 let removeById = (list, ids) => { 170 let node = list._first 171 do { 172 if (node.element == undefined) break; 173 let shouldRemove = ids.includes(node.element?.command?.id) 174 if (shouldRemove) { list._remove(node) } 175 } while ((node = node.next)) 176 } 177 178 removeById(contextMenuLinks, removableIds) 179 } 180 </script> 181 </body> 182 </html>