mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Allow new file and edit file preview if it has editable extension (#23624)
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>
This commit is contained in:
		
							
								
								
									
										9
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -37,6 +37,7 @@
 | 
				
			|||||||
        "pretty-ms": "8.0.0",
 | 
					        "pretty-ms": "8.0.0",
 | 
				
			||||||
        "sortablejs": "1.15.0",
 | 
					        "sortablejs": "1.15.0",
 | 
				
			||||||
        "swagger-ui-dist": "4.18.1",
 | 
					        "swagger-ui-dist": "4.18.1",
 | 
				
			||||||
 | 
					        "throttle-debounce": "5.0.0",
 | 
				
			||||||
        "tippy.js": "6.3.7",
 | 
					        "tippy.js": "6.3.7",
 | 
				
			||||||
        "tributejs": "5.1.3",
 | 
					        "tributejs": "5.1.3",
 | 
				
			||||||
        "uint8-to-base64": "0.2.0",
 | 
					        "uint8-to-base64": "0.2.0",
 | 
				
			||||||
@@ -8839,6 +8840,14 @@
 | 
				
			|||||||
      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
 | 
					      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
 | 
				
			||||||
      "dev": true
 | 
					      "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": {
 | 
					    "node_modules/tinybench": {
 | 
				
			||||||
      "version": "2.4.0",
 | 
					      "version": "2.4.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.4.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.4.0.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@
 | 
				
			|||||||
    "pretty-ms": "8.0.0",
 | 
					    "pretty-ms": "8.0.0",
 | 
				
			||||||
    "sortablejs": "1.15.0",
 | 
					    "sortablejs": "1.15.0",
 | 
				
			||||||
    "swagger-ui-dist": "4.18.1",
 | 
					    "swagger-ui-dist": "4.18.1",
 | 
				
			||||||
 | 
					    "throttle-debounce": "5.0.0",
 | 
				
			||||||
    "tippy.js": "6.3.7",
 | 
					    "tippy.js": "6.3.7",
 | 
				
			||||||
    "tributejs": "5.1.3",
 | 
					    "tributejs": "5.1.3",
 | 
				
			||||||
    "uint8-to-base64": "0.2.0",
 | 
					    "uint8-to-base64": "0.2.0",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,8 +30,8 @@
 | 
				
			|||||||
			<div class="field">
 | 
								<div class="field">
 | 
				
			||||||
				<div class="ui top attached tabular menu" data-write="write" data-preview="preview" data-diff="diff">
 | 
									<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>
 | 
										<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>
 | 
										<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>
 | 
										<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}}
 | 
										{{end}}
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
import {basename, extname, isObject, isDarkTheme} from '../utils.js';
 | 
					import {basename, extname, isObject, isDarkTheme} from '../utils.js';
 | 
				
			||||||
 | 
					import {debounce} from 'throttle-debounce';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const languagesByFilename = {};
 | 
					const languagesByFilename = {};
 | 
				
			||||||
const languagesByExt = {};
 | 
					const languagesByExt = {};
 | 
				
			||||||
@@ -130,23 +131,33 @@ function getFileBasedOptions(filename, lineWrapExts) {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function createCodeEditor(textarea, filenameInput) {
 | 
					function togglePreviewDisplay(previewable) {
 | 
				
			||||||
  const filename = basename(filenameInput.value);
 | 
					  const previewTab = document.querySelector('a[data-tab="preview"]');
 | 
				
			||||||
  const previewLink = document.querySelector('a[data-tab=preview]');
 | 
					  if (!previewTab) return;
 | 
				
			||||||
  const previewableExts = (textarea.getAttribute('data-previewable-extensions') || '').split(',');
 | 
					 | 
				
			||||||
  const lineWrapExts = (textarea.getAttribute('data-line-wrap-extensions') || '').split(',');
 | 
					 | 
				
			||||||
  const previewable = previewableExts.includes(extname(filename));
 | 
					 | 
				
			||||||
  const editorConfig = getEditorconfig(filenameInput);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (previewLink) {
 | 
					  if (previewable) {
 | 
				
			||||||
    if (previewable) {
 | 
					    const newUrl = (previewTab.getAttribute('data-url') || '').replace(/(.*)\/.*/i, `$1/markup`);
 | 
				
			||||||
      const newUrl = (previewLink.getAttribute('data-url') || '').replace(/(.*)\/.*/i, `$1/markup`);
 | 
					    previewTab.setAttribute('data-url', newUrl);
 | 
				
			||||||
      previewLink.setAttribute('data-url', newUrl);
 | 
					    previewTab.style.display = '';
 | 
				
			||||||
      previewLink.style.display = '';
 | 
					  } else {
 | 
				
			||||||
    } else {
 | 
					    previewTab.style.display = 'none';
 | 
				
			||||||
      previewLink.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 previewableExts = new Set((textarea.getAttribute('data-previewable-extensions') || '').split(','));
 | 
				
			||||||
 | 
					  const lineWrapExts = (textarea.getAttribute('data-line-wrap-extensions') || '').split(',');
 | 
				
			||||||
 | 
					  const previewable = previewableExts.has(extname(filename));
 | 
				
			||||||
 | 
					  const editorConfig = getEditorconfig(filenameInput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  togglePreviewDisplay(previewable);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const {monaco, editor} = await createMonaco(textarea, filename, {
 | 
					  const {monaco, editor} = await createMonaco(textarea, filename, {
 | 
				
			||||||
    ...baseOptions,
 | 
					    ...baseOptions,
 | 
				
			||||||
@@ -154,10 +165,12 @@ export async function createCodeEditor(textarea, filenameInput) {
 | 
				
			|||||||
    ...getEditorConfigOptions(editorConfig),
 | 
					    ...getEditorConfigOptions(editorConfig),
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  filenameInput.addEventListener('keyup', () => {
 | 
					  filenameInput.addEventListener('input', debounce(500, () => {
 | 
				
			||||||
    const filename = filenameInput.value;
 | 
					    const filename = filenameInput.value;
 | 
				
			||||||
 | 
					    const previewable = previewableExts.has(extname(filename));
 | 
				
			||||||
 | 
					    togglePreviewDisplay(previewable);
 | 
				
			||||||
    updateEditor(monaco, editor, filename, lineWrapExts);
 | 
					    updateEditor(monaco, editor, filename, lineWrapExts);
 | 
				
			||||||
  });
 | 
					  }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return editor;
 | 
					  return editor;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user