diff options
author | silverwind <me@silverwind.io> | 2020-11-14 04:57:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-13 22:57:34 -0500 |
commit | 374ff60465ace2471d0dde121c6a3e1527ab0bec (patch) | |
tree | 76070c023124891a4ee08da8b5db01e13bf90d65 /web_src | |
parent | a2efcb6acc85dbd231c402a4c308e76289d06cbd (diff) | |
download | gitea-374ff60465ace2471d0dde121c6a3e1527ab0bec.tar.gz gitea-374ff60465ace2471d0dde121c6a3e1527ab0bec.zip |
Use monaco for the git hook editor (#13552)
Migrate git hook editor to monaco, replacing CodeMirror. Had to do a few
refactors to make the monaco instantiation generic enough to be of use.
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Diffstat (limited to 'web_src')
-rw-r--r-- | web_src/js/features/codeeditor.js | 97 | ||||
-rw-r--r-- | web_src/js/index.js | 17 | ||||
-rw-r--r-- | web_src/less/_editor.less | 9 |
3 files changed, 67 insertions, 56 deletions
diff --git a/web_src/js/features/codeeditor.js b/web_src/js/features/codeeditor.js index d9ddb58d00..3b6864ffe7 100644 --- a/web_src/js/features/codeeditor.js +++ b/web_src/js/features/codeeditor.js @@ -26,12 +26,11 @@ function getLanguage(filename) { return languagesByFilename[filename] || languagesByExt[extname(filename)] || 'plaintext'; } -function updateEditor(monaco, editor, filenameInput) { - const newFilename = filenameInput.value; - editor.updateOptions(getOptions(filenameInput)); +function updateEditor(monaco, editor, filename, lineWrapExts) { + editor.updateOptions({...getFileBasedOptions(filename, lineWrapExts)}); const model = editor.getModel(); const language = model.getModeId(); - const newLanguage = getLanguage(newFilename); + const newLanguage = getLanguage(filename); if (language !== newLanguage) monaco.editor.setModelLanguage(model, newLanguage); } @@ -41,24 +40,12 @@ function exportEditor(editor) { if (!window.codeEditors.includes(editor)) window.codeEditors.push(editor); } -export async function createCodeEditor(textarea, filenameInput, previewFileModes) { - const filename = basename(filenameInput.value); - const previewLink = document.querySelector('a[data-tab=preview]'); - const markdownExts = (textarea.dataset.markdownFileExts || '').split(','); - const lineWrapExts = (textarea.dataset.lineWrapExtensions || '').split(','); - const isMarkdown = markdownExts.includes(extname(filename)); - - if (previewLink) { - if (isMarkdown && (previewFileModes || []).includes('markdown')) { - previewLink.dataset.url = previewLink.dataset.url.replace(/(.*)\/.*/i, `$1/markdown`); - previewLink.style.display = ''; - } else { - previewLink.style.display = 'none'; - } - } - +export async function createMonaco(textarea, filename, editorOpts) { const monaco = await import(/* webpackChunkName: "monaco" */'monaco-editor'); + initLanguages(monaco); + let {language, ...other} = editorOpts; + if (!language) language = getLanguage(filename); const container = document.createElement('div'); container.className = 'monaco-editor-container'; @@ -66,8 +53,9 @@ export async function createCodeEditor(textarea, filenameInput, previewFileModes const editor = monaco.editor.create(container, { value: textarea.value, - language: getLanguage(filename), - ...getOptions(filenameInput, lineWrapExts), + theme: isDarkTheme() ? 'vs-dark' : 'vs', + language, + ...other, }); const model = editor.getModel(); @@ -80,33 +68,60 @@ export async function createCodeEditor(textarea, filenameInput, previewFileModes editor.layout(); }); - filenameInput.addEventListener('keyup', () => { - updateEditor(monaco, editor, filenameInput); - }); + exportEditor(editor); const loading = document.querySelector('.editor-loading'); if (loading) loading.remove(); - exportEditor(editor); + return {monaco, editor}; +} - return editor; +function getFileBasedOptions(filename, lineWrapExts) { + return { + wordWrap: (lineWrapExts || []).includes(extname(filename)) ? 'on' : 'off', + }; } -function getOptions(filenameInput, lineWrapExts) { - const ec = getEditorconfig(filenameInput); - const theme = isDarkTheme() ? 'vs-dark' : 'vs'; - const wordWrap = (lineWrapExts || []).includes(extname(filenameInput.value)) ? 'on' : 'off'; - - const opts = {theme, wordWrap}; - if (isObject(ec)) { - opts.detectIndentation = !('indent_style' in ec) || !('indent_size' in ec); - if ('indent_size' in ec) opts.indentSize = Number(ec.indent_size); - if ('tab_width' in ec) opts.tabSize = Number(ec.tab_width) || opts.indentSize; - if ('max_line_length' in ec) opts.rulers = [Number(ec.max_line_length)]; - opts.trimAutoWhitespace = ec.trim_trailing_whitespace === true; - opts.insertSpaces = ec.indent_style === 'space'; - opts.useTabStops = ec.indent_style === 'tab'; +export async function createCodeEditor(textarea, filenameInput, previewFileModes) { + const filename = basename(filenameInput.value); + const previewLink = document.querySelector('a[data-tab=preview]'); + const markdownExts = (textarea.dataset.markdownFileExts || '').split(','); + const lineWrapExts = (textarea.dataset.lineWrapExtensions || '').split(','); + const isMarkdown = markdownExts.includes(extname(filename)); + const editorConfig = getEditorconfig(filenameInput); + + if (previewLink) { + if (isMarkdown && (previewFileModes || []).includes('markdown')) { + previewLink.dataset.url = previewLink.dataset.url.replace(/(.*)\/.*/i, `$1/markdown`); + previewLink.style.display = ''; + } else { + previewLink.style.display = 'none'; + } } + const {monaco, editor} = await createMonaco(textarea, filename, { + ...getFileBasedOptions(filenameInput.value, lineWrapExts), + ...getEditorConfigOptions(editorConfig), + }); + + filenameInput.addEventListener('keyup', () => { + const filename = filenameInput.value; + updateEditor(monaco, editor, filename, lineWrapExts); + }); + + return editor; +} + +function getEditorConfigOptions(ec) { + if (!isObject(ec)) return {}; + + const opts = {}; + opts.detectIndentation = !('indent_style' in ec) || !('indent_size' in ec); + if ('indent_size' in ec) opts.indentSize = Number(ec.indent_size); + if ('tab_width' in ec) opts.tabSize = Number(ec.tab_width) || opts.indentSize; + if ('max_line_length' in ec) opts.rulers = [Number(ec.max_line_length)]; + opts.trimAutoWhitespace = ec.trim_trailing_whitespace === true; + opts.insertSpaces = ec.indent_style === 'space'; + opts.useTabStops = ec.indent_style === 'tab'; return opts; } diff --git a/web_src/js/index.js b/web_src/js/index.js index 08305043d4..1d36dcf6b2 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -23,7 +23,7 @@ import createDropzone from './features/dropzone.js'; import initTableSort from './features/tablesort.js'; import ActivityTopAuthors from './components/ActivityTopAuthors.vue'; import {initNotificationsTable, initNotificationCount} from './features/notification.js'; -import {createCodeEditor} from './features/codeeditor.js'; +import {createCodeEditor, createMonaco} from './features/codeeditor.js'; import {svg, svgs} from './svg.js'; import {stripTags} from './utils.js'; @@ -1732,15 +1732,10 @@ function initUserSettings() { } } -function initGithook() { - if ($('.edit.githook').length === 0) { - return; - } - - CodeMirror.autoLoadMode(CodeMirror.fromTextArea($('#content')[0], { - lineNumbers: true, - mode: 'shell' - }), 'shell'); +async function initGithook() { + if ($('.edit.githook').length === 0) return; + const filename = document.querySelector('.hook-filename').textContent; + await createMonaco($('#content')[0], filename, {language: 'shell'}); } function initWebhook() { @@ -2517,7 +2512,6 @@ $(document).ready(async () => { initEditForm(); initEditor(); initOrganization(); - initGithook(); initWebhook(); initAdmin(); initCodeView(); @@ -2575,6 +2569,7 @@ $(document).ready(async () => { initServiceWorker(), initNotificationCount(), renderMarkdownContent(), + initGithook(), ]); }); diff --git a/web_src/less/_editor.less b/web_src/less/_editor.less index 4ed211a628..bb69960646 100644 --- a/web_src/less/_editor.less +++ b/web_src/less/_editor.less @@ -53,10 +53,6 @@ border-right: 1px solid var(--color-secondary) !important; } -#edit_area { - display: none; -} - .monaco-editor-container { width: 100%; min-height: 200px; @@ -73,3 +69,8 @@ color: transparent !important; background-color: transparent !important; } + +.edit.githook .monaco-editor-container { + border: 1px solid var(--color-secondary); + height: 70vh; +} |