/ src / Monaco / index.html
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>