diff options
-rw-r--r-- | package-lock.json | 9 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | templates/repo/editor/edit.tmpl | 2 | ||||
-rw-r--r-- | web_src/js/features/codeeditor.js | 41 |
4 files changed, 38 insertions, 15 deletions
diff --git a/package-lock.json b/package-lock.json index 2f277f180f..93adf5622f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "pretty-ms": "8.0.0", "sortablejs": "1.15.0", "swagger-ui-dist": "4.18.1", + "throttle-debounce": "5.0.0", "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", @@ -8839,6 +8840,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/throttle-debounce": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", + "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==", + "engines": { + "node": ">=12.22" + } + }, "node_modules/tinybench": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.4.0.tgz", diff --git a/package.json b/package.json index e5f346f207..a5d09157a6 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "pretty-ms": "8.0.0", "sortablejs": "1.15.0", "swagger-ui-dist": "4.18.1", + "throttle-debounce": "5.0.0", "tippy.js": "6.3.7", "tributejs": "5.1.3", "uint8-to-base64": "0.2.0", diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl index 2a3c404d1a..6ecc5e1460 100644 --- a/templates/repo/editor/edit.tmpl +++ b/templates/repo/editor/edit.tmpl @@ -30,8 +30,8 @@ <div class="field"> <div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff"> <a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{.locale.Tr "repo.editor.new_file"}}{{else}}{{.locale.Tr "repo.editor.edit_file"}}{{end}}</a> - {{if not .IsNewFile}} <a class="item" data-tab="preview" data-url="{{.Repository.Link}}/markup" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL}}" data-markup-mode="file">{{svg "octicon-eye"}} {{.locale.Tr "preview"}}</a> + {{if not .IsNewFile}} <a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}" data-context="{{.BranchLink}}">{{svg "octicon-diff"}} {{.locale.Tr "repo.editor.preview_changes"}}</a> {{end}} </div> diff --git a/web_src/js/features/codeeditor.js b/web_src/js/features/codeeditor.js index 4f5ea317b4..40bc6d618f 100644 --- a/web_src/js/features/codeeditor.js +++ b/web_src/js/features/codeeditor.js @@ -1,4 +1,5 @@ import {basename, extname, isObject, isDarkTheme} from '../utils.js'; +import {debounce} from 'throttle-debounce'; const languagesByFilename = {}; const languagesByExt = {}; @@ -130,23 +131,33 @@ function getFileBasedOptions(filename, lineWrapExts) { }; } +function togglePreviewDisplay(previewable) { + const previewTab = document.querySelector('a[data-tab="preview"]'); + if (!previewTab) return; + + if (previewable) { + const newUrl = (previewTab.getAttribute('data-url') || '').replace(/(.*)\/.*/i, `$1/markup`); + previewTab.setAttribute('data-url', newUrl); + previewTab.style.display = ''; + } else { + previewTab.style.display = 'none'; + // If the "preview" tab was active, user changes the filename to a non-previewable one, + // then the "preview" tab becomes inactive (hidden), so the "write" tab should become active + if (previewTab.classList.contains('active')) { + const writeTab = document.querySelector('a[data-tab="write"]'); + writeTab.click(); + } + } +} + export async function createCodeEditor(textarea, filenameInput) { const filename = basename(filenameInput.value); - const previewLink = document.querySelector('a[data-tab=preview]'); - const previewableExts = (textarea.getAttribute('data-previewable-extensions') || '').split(','); + const previewableExts = new Set((textarea.getAttribute('data-previewable-extensions') || '').split(',')); const lineWrapExts = (textarea.getAttribute('data-line-wrap-extensions') || '').split(','); - const previewable = previewableExts.includes(extname(filename)); + const previewable = previewableExts.has(extname(filename)); const editorConfig = getEditorconfig(filenameInput); - if (previewLink) { - if (previewable) { - const newUrl = (previewLink.getAttribute('data-url') || '').replace(/(.*)\/.*/i, `$1/markup`); - previewLink.setAttribute('data-url', newUrl); - previewLink.style.display = ''; - } else { - previewLink.style.display = 'none'; - } - } + togglePreviewDisplay(previewable); const {monaco, editor} = await createMonaco(textarea, filename, { ...baseOptions, @@ -154,10 +165,12 @@ export async function createCodeEditor(textarea, filenameInput) { ...getEditorConfigOptions(editorConfig), }); - filenameInput.addEventListener('keyup', () => { + filenameInput.addEventListener('input', debounce(500, () => { const filename = filenameInput.value; + const previewable = previewableExts.has(extname(filename)); + togglePreviewDisplay(previewable); updateEditor(monaco, editor, filename, lineWrapExts); - }); + })); return editor; } |