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/js/features | |
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/js/features')
-rw-r--r-- | web_src/js/features/codeeditor.js | 97 |
1 files changed, 56 insertions, 41 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; } |