]> source.dussan.org Git - gitea.git/commitdiff
Allow new file and edit file preview if it has editable extension (#23624)
authorHester Gong <hestergong@gmail.com>
Sun, 26 Mar 2023 05:25:41 +0000 (13:25 +0800)
committerGitHub <noreply@github.com>
Sun, 26 Mar 2023 05:25:41 +0000 (13:25 +0800)
Close #23579
Inspired by
[idea](https://github.com/go-gitea/gitea/issues/23579#issuecomment-1475429247)
from @brechtvl
In this PR, the behavior is when extension switches from writatble to
not, preview will hide, and vice versa.

demo:

https://user-images.githubusercontent.com/17645053/226786119-d20063da-8763-41ce-9b00-ae34929120e1.mov

---------

Co-authored-by: silverwind <me@silverwind.io>
package-lock.json
package.json
templates/repo/editor/edit.tmpl
web_src/js/features/codeeditor.js

index 2f277f180f30787e29c196f60d186f796a7795bb..93adf5622f83bc3578c9b7b670728770c98a812d 100644 (file)
@@ -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",
       "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",
index e5f346f207b924fe31dee40928c40426d6103a4b..a5d09157a65dca8ce9c9f84563904b790cd3b436 100644 (file)
@@ -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",
index 2a3c404d1a6f2115043571f4771345f9caf883ed..6ecc5e1460c3cecc8ff3a895f8c5ac1c7979652c 100644 (file)
@@ -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>
index 4f5ea317b47672539c1284fe8ceb3338c8916922..40bc6d618f547cf06ce3d51798550fd4abce70f2 100644 (file)
@@ -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;
 }