summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package-lock.json9
-rw-r--r--package.json1
-rw-r--r--templates/repo/editor/edit.tmpl2
-rw-r--r--web_src/js/features/codeeditor.js41
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;
}