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:
parent
2d2b4bdf62
commit
ac64c82974
4 changed files with 40 additions and 17 deletions
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) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
export async function createCodeEditor(textarea, filenameInput) {
|
||||||
const filename = basename(filenameInput.value);
|
const filename = basename(filenameInput.value);
|
||||||
const previewLink = document.querySelector('a[data-tab=preview]');
|
const previewableExts = new Set((textarea.getAttribute('data-previewable-extensions') || '').split(','));
|
||||||
const previewableExts = (textarea.getAttribute('data-previewable-extensions') || '').split(',');
|
|
||||||
const lineWrapExts = (textarea.getAttribute('data-line-wrap-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);
|
const editorConfig = getEditorconfig(filenameInput);
|
||||||
|
|
||||||
if (previewLink) {
|
togglePreviewDisplay(previewable);
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue