code.gitea.io/gitea@v1.22.3/web_src/js/features/repo-wiki.js (about) 1 import {initMarkupContent} from '../markup/content.js'; 2 import {validateTextareaNonEmpty, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js'; 3 import {fomanticMobileScreen} from '../modules/fomantic.js'; 4 import {POST} from '../modules/fetch.js'; 5 6 async function initRepoWikiFormEditor() { 7 const editArea = document.querySelector('.repository.wiki .combo-markdown-editor textarea'); 8 if (!editArea) return; 9 10 const form = document.querySelector('.repository.wiki.new .ui.form'); 11 const editorContainer = form.querySelector('.combo-markdown-editor'); 12 let editor; 13 14 let renderRequesting = false; 15 let lastContent; 16 const renderEasyMDEPreview = async function () { 17 if (renderRequesting) return; 18 19 const previewFull = editorContainer.querySelector('.EasyMDEContainer .editor-preview-active'); 20 const previewSide = editorContainer.querySelector('.EasyMDEContainer .editor-preview-active-side'); 21 const previewTarget = previewSide || previewFull; 22 const newContent = editArea.value; 23 if (editor && previewTarget && lastContent !== newContent) { 24 renderRequesting = true; 25 const formData = new FormData(); 26 formData.append('mode', editor.previewMode); 27 formData.append('context', editor.previewContext); 28 formData.append('text', newContent); 29 formData.append('wiki', editor.previewWiki); 30 try { 31 const response = await POST(editor.previewUrl, {data: formData}); 32 const data = await response.text(); 33 lastContent = newContent; 34 previewTarget.innerHTML = `<div class="markup ui segment">${data}</div>`; 35 initMarkupContent(); 36 } catch (error) { 37 console.error('Error rendering preview:', error); 38 } finally { 39 renderRequesting = false; 40 setTimeout(renderEasyMDEPreview, 1000); 41 } 42 } else { 43 setTimeout(renderEasyMDEPreview, 1000); 44 } 45 }; 46 renderEasyMDEPreview(); 47 48 editor = await initComboMarkdownEditor(editorContainer, { 49 useScene: 'wiki', 50 // EasyMDE has some problems of height definition, it has inline style height 300px by default, so we also use inline styles to override it. 51 // And another benefit is that we only need to write the style once for both editors. 52 // TODO: Move height style to CSS after EasyMDE removal. 53 editorHeights: {minHeight: '300px', height: 'calc(100vh - 600px)'}, 54 previewMode: 'gfm', 55 previewWiki: true, 56 easyMDEOptions: { 57 previewRender: (_content, previewTarget) => previewTarget.innerHTML, // disable builtin preview render 58 toolbar: ['bold', 'italic', 'strikethrough', '|', 59 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|', 60 'gitea-code-inline', 'code', 'quote', '|', 'gitea-checkbox-empty', 'gitea-checkbox-checked', '|', 61 'unordered-list', 'ordered-list', '|', 62 'link', 'image', 'table', 'horizontal-rule', '|', 63 'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea', 64 ], 65 }, 66 }); 67 68 form.addEventListener('submit', (e) => { 69 if (!validateTextareaNonEmpty(editArea)) { 70 e.preventDefault(); 71 e.stopPropagation(); 72 } 73 }); 74 } 75 76 function collapseWikiTocForMobile(collapse) { 77 if (collapse) { 78 document.querySelector('.wiki-content-toc details')?.removeAttribute('open'); 79 } 80 } 81 82 export function initRepoWikiForm() { 83 if (!document.querySelector('.page-content.repository.wiki')) return; 84 85 fomanticMobileScreen.addEventListener('change', (e) => collapseWikiTocForMobile(e.matches)); 86 collapseWikiTocForMobile(fomanticMobileScreen.matches); 87 88 initRepoWikiFormEditor(); 89 }