aboutsummaryrefslogtreecommitdiffstats
path: root/web_src/js/features/repo-wiki.js
diff options
context:
space:
mode:
Diffstat (limited to 'web_src/js/features/repo-wiki.js')
-rw-r--r--web_src/js/features/repo-wiki.js220
1 files changed, 47 insertions, 173 deletions
diff --git a/web_src/js/features/repo-wiki.js b/web_src/js/features/repo-wiki.js
index 4555b32e5f..a48f63dcb1 100644
--- a/web_src/js/features/repo-wiki.js
+++ b/web_src/js/features/repo-wiki.js
@@ -1,194 +1,68 @@
import $ from 'jquery';
import {initMarkupContent} from '../markup/content.js';
-import {attachEasyMDEToElements, codeMirrorQuickSubmit, importEasyMDE, validateTextareaNonEmpty} from './comp/EasyMDE.js';
-import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js';
+import {validateTextareaNonEmpty, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js';
const {csrfToken} = window.config;
async function initRepoWikiFormEditor() {
- const $editArea = $('.repository.wiki textarea#edit_area');
+ const $editArea = $('.repository.wiki .combo-markdown-editor textarea');
if (!$editArea.length) return;
- let sideBySideChanges = 0;
- let sideBySideTimeout = null;
- let hasEasyMDE = true;
-
const $form = $('.repository.wiki.new .ui.form');
- const EasyMDE = await importEasyMDE();
- const easyMDE = new EasyMDE({
- autoDownloadFontAwesome: false,
- element: $editArea[0],
- forceSync: true,
- previewRender(plainText, preview) { // Async method
- // FIXME: still send render request when return back to edit mode
- const render = function () {
- sideBySideChanges = 0;
- if (sideBySideTimeout !== null) {
- clearTimeout(sideBySideTimeout);
- sideBySideTimeout = null;
- }
- $.post($editArea.data('url'), {
- _csrf: csrfToken,
- mode: 'gfm',
- context: $editArea.data('context'),
- text: plainText,
- wiki: true
- }, (data) => {
- preview.innerHTML = `<div class="markup ui segment">${data}</div>`;
- initMarkupContent();
- });
- };
+ const $editorContainer = $form.find('.combo-markdown-editor');
+ let editor;
- setTimeout(() => {
- if (!easyMDE.isSideBySideActive()) {
- render();
- } else {
- // delay preview by keystroke counting
- sideBySideChanges++;
- if (sideBySideChanges > 10) {
- render();
- }
- // or delay preview by timeout
- if (sideBySideTimeout !== null) {
- clearTimeout(sideBySideTimeout);
- sideBySideTimeout = null;
- }
- sideBySideTimeout = setTimeout(render, 600);
- }
- }, 0);
- if (!easyMDE.isSideBySideActive()) {
- return 'Loading...';
- }
- return preview.innerHTML;
- },
- renderingConfig: {
- singleLineBreaks: false
- },
- indentWithTabs: false,
- tabSize: 4,
- spellChecker: false,
- inputStyle: 'contenteditable', // nativeSpellcheck requires contenteditable
- nativeSpellcheck: true,
- toolbar: ['bold', 'italic', 'strikethrough', '|',
- 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|',
- {
- name: 'code-inline',
- action(e) {
- const cm = e.codemirror;
- const selection = cm.getSelection();
- cm.replaceSelection(`\`${selection}\``);
- if (!selection) {
- const cursorPos = cm.getCursor();
- cm.setCursor(cursorPos.line, cursorPos.ch - 1);
- }
- cm.focus();
- },
- className: 'fa fa-angle-right',
- title: 'Add Inline Code',
- }, 'code', 'quote', '|', {
- name: 'checkbox-empty',
- action(e) {
- const cm = e.codemirror;
- cm.replaceSelection(`\n- [ ] ${cm.getSelection()}`);
- cm.focus();
- },
- className: 'fa fa-square-o',
- title: 'Add Checkbox (empty)',
- },
- {
- name: 'checkbox-checked',
- action(e) {
- const cm = e.codemirror;
- cm.replaceSelection(`\n- [x] ${cm.getSelection()}`);
- cm.focus();
- },
- className: 'fa fa-check-square-o',
- title: 'Add Checkbox (checked)',
- }, '|',
- 'unordered-list', 'ordered-list', '|',
- 'link', 'image', 'table', 'horizontal-rule', '|',
- 'clean-block', 'preview', 'fullscreen', 'side-by-side', '|',
- {
- name: 'revert-to-textarea',
- action(e) {
- e.toTextArea();
- hasEasyMDE = false;
- const $root = $form.find('.field.content');
- const loading = $root.data('loading');
- $root.append(`<div class="ui bottom tab markup" data-tab="preview">${loading}</div>`);
- initCompMarkupContentPreviewTab($form);
- },
- className: 'fa fa-file',
- title: 'Revert to simple textarea',
- },
- ]
- });
+ let renderRequesting = false;
+ let lastContent;
+ const renderEasyMDEPreview = function () {
+ if (renderRequesting) return;
- easyMDE.codemirror.setOption('extraKeys', {
- 'Cmd-Enter': codeMirrorQuickSubmit,
- 'Ctrl-Enter': codeMirrorQuickSubmit,
- });
+ const $previewFull = $editorContainer.find('.EasyMDEContainer .editor-preview-active');
+ const $previewSide = $editorContainer.find('.EasyMDEContainer .editor-preview-active-side');
+ const $previewTarget = $previewSide.length ? $previewSide : $previewFull;
+ const newContent = $editArea.val();
+ if (editor && $previewTarget.length && lastContent !== newContent) {
+ renderRequesting = true;
+ $.post(editor.previewUrl, {
+ _csrf: csrfToken,
+ mode: editor.previewMode,
+ context: editor.previewContext,
+ text: newContent,
+ wiki: editor.previewWiki,
+ }).done((data) => {
+ lastContent = newContent;
+ $previewTarget.html(`<div class="markup ui segment">${data}</div>`);
+ initMarkupContent();
+ }).always(() => {
+ renderRequesting = false;
+ setTimeout(renderEasyMDEPreview, 1000);
+ });
+ } else {
+ setTimeout(renderEasyMDEPreview, 1000);
+ }
+ };
+ renderEasyMDEPreview();
- attachEasyMDEToElements(easyMDE);
+ editor = await initComboMarkdownEditor($editorContainer, {
+ previewMode: 'gfm',
+ previewWiki: true,
+ easyMDEOptions: {
+ previewRender: (_content, previewTarget) => previewTarget.innerHTML, // disable builtin preview render
+ toolbar: ['bold', 'italic', 'strikethrough', '|',
+ 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|',
+ 'gitea-code-inline', 'code', 'quote', '|', 'gitea-checkbox-empty', 'gitea-checkbox-checked', '|',
+ 'unordered-list', 'ordered-list', '|',
+ 'link', 'image', 'table', 'horizontal-rule', '|',
+ 'clean-block', 'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea'
+ ],
+ },
+ });
$form.on('submit', () => {
if (!validateTextareaNonEmpty($editArea)) {
return false;
}
});
-
- setTimeout(() => {
- const $bEdit = $('.repository.wiki.new .previewtabs a[data-tab="write"]');
- const $bPrev = $('.repository.wiki.new .previewtabs a[data-tab="preview"]');
- const $toolbar = $('.editor-toolbar');
- const $bPreview = $('.editor-toolbar button.preview');
- const $bSideBySide = $('.editor-toolbar a.fa-columns');
- $bEdit.on('click', (e) => {
- if (!hasEasyMDE) {
- return false;
- }
- e.stopImmediatePropagation();
- if ($toolbar.hasClass('disabled-for-preview')) {
- $bPreview.trigger('click');
- }
-
- return false;
- });
- $bPrev.on('click', (e) => {
- if (!hasEasyMDE) {
- return false;
- }
- e.stopImmediatePropagation();
- if (!$toolbar.hasClass('disabled-for-preview')) {
- $bPreview.trigger('click');
- }
- return false;
- });
- $bPreview.on('click', () => {
- setTimeout(() => {
- if ($toolbar.hasClass('disabled-for-preview')) {
- if ($bEdit.hasClass('active')) {
- $bEdit.removeClass('active');
- }
- if (!$bPrev.hasClass('active')) {
- $bPrev.addClass('active');
- }
- } else {
- if (!$bEdit.hasClass('active')) {
- $bEdit.addClass('active');
- }
- if ($bPrev.hasClass('active')) {
- $bPrev.removeClass('active');
- }
- }
- }, 0);
-
- return false;
- });
- $bSideBySide.on('click', () => {
- sideBySideChanges = 10;
- });
- }, 0);
}
export function initRepoWikiForm() {