aboutsummaryrefslogtreecommitdiffstats
path: root/web_src/js/features
diff options
context:
space:
mode:
Diffstat (limited to 'web_src/js/features')
-rw-r--r--web_src/js/features/common-form.ts8
-rw-r--r--web_src/js/features/comp/ComboMarkdownEditor.ts58
-rw-r--r--web_src/js/features/repo-editor.ts8
-rw-r--r--web_src/js/features/repo-issue.ts5
-rw-r--r--web_src/js/features/repo-release.ts10
-rw-r--r--web_src/js/features/repo-wiki.ts7
6 files changed, 48 insertions, 48 deletions
diff --git a/web_src/js/features/common-form.ts b/web_src/js/features/common-form.ts
index 1aca93169d..86323e352e 100644
--- a/web_src/js/features/common-form.ts
+++ b/web_src/js/features/common-form.ts
@@ -1,5 +1,7 @@
import {applyAreYouSure, initAreYouSure} from '../vendor/jquery.are-you-sure.ts';
import {handleGlobalEnterQuickSubmit} from './comp/QuickSubmit.ts';
+import {queryElems} from '../utils/dom.ts';
+import {initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
export function initGlobalFormDirtyLeaveConfirm() {
initAreYouSure(window.jQuery);
@@ -11,7 +13,7 @@ export function initGlobalFormDirtyLeaveConfirm() {
}
export function initGlobalEnterQuickSubmit() {
- document.addEventListener('keydown', (e) => {
+ document.addEventListener('keydown', (e: KeyboardEvent & {target: HTMLElement}) => {
if (e.key !== 'Enter') return;
const hasCtrlOrMeta = ((e.ctrlKey || e.metaKey) && !e.altKey);
if (hasCtrlOrMeta && e.target.matches('textarea')) {
@@ -27,3 +29,7 @@ export function initGlobalEnterQuickSubmit() {
}
});
}
+
+export function initGlobalComboMarkdownEditor() {
+ queryElems<HTMLElement>(document, '.combo-markdown-editor:not(.custom-init)', (el) => initComboMarkdownEditor(el));
+}
diff --git a/web_src/js/features/comp/ComboMarkdownEditor.ts b/web_src/js/features/comp/ComboMarkdownEditor.ts
index 7117952fa3..80eabaa37a 100644
--- a/web_src/js/features/comp/ComboMarkdownEditor.ts
+++ b/web_src/js/features/comp/ComboMarkdownEditor.ts
@@ -1,6 +1,5 @@
import '@github/markdown-toolbar-element';
import '@github/text-expander-element';
-import $ from 'jquery';
import {attachTribute} from '../tribute.ts';
import {hideElem, showElem, autosize, isElemVisible} from '../../utils/dom.ts';
import {
@@ -23,6 +22,8 @@ import {
} from './EditorMarkdown.ts';
import {DropzoneCustomEventReloadFiles, initDropzone} from '../dropzone.ts';
import {createTippy} from '../../modules/tippy.ts';
+import {fomanticQuery} from '../../modules/fomantic/base.ts';
+import type EasyMDE from 'easymde';
let elementIdCounter = 0;
@@ -48,18 +49,23 @@ export function validateTextareaNonEmpty(textarea) {
return true;
}
+type ComboMarkdownEditorOptions = {
+ editorHeights?: {minHeight?: string, height?: string, maxHeight?: string},
+ easyMDEOptions?: EasyMDE.Options,
+};
+
export class ComboMarkdownEditor {
static EventEditorContentChanged = EventEditorContentChanged;
static EventUploadStateChanged = EventUploadStateChanged;
public container : HTMLElement;
- // TODO: use correct types to replace these "any" types
- options: any;
+ options: ComboMarkdownEditorOptions;
tabEditor: HTMLElement;
tabPreviewer: HTMLElement;
+ supportEasyMDE: boolean;
easyMDE: any;
easyMDEToolbarActions: any;
easyMDEToolbarDefault: any;
@@ -71,11 +77,12 @@ export class ComboMarkdownEditor {
dropzone: HTMLElement;
attachedDropzoneInst: any;
+ previewMode: string;
previewUrl: string;
previewContext: string;
- previewMode: string;
- constructor(container, options = {}) {
+ constructor(container, options:ComboMarkdownEditorOptions = {}) {
+ if (container._giteaComboMarkdownEditor) throw new Error('ComboMarkdownEditor already initialized');
container._giteaComboMarkdownEditor = this;
this.options = options;
this.container = container;
@@ -99,6 +106,10 @@ export class ComboMarkdownEditor {
}
setupContainer() {
+ this.supportEasyMDE = this.container.getAttribute('data-support-easy-mde') === 'true';
+ this.previewMode = this.container.getAttribute('data-content-mode');
+ this.previewUrl = this.container.getAttribute('data-preview-url');
+ this.previewContext = this.container.getAttribute('data-preview-context');
initTextExpander(this.container.querySelector('text-expander'));
}
@@ -137,12 +148,14 @@ export class ComboMarkdownEditor {
monospaceButton.setAttribute('aria-checked', String(enabled));
});
- const easymdeButton = this.container.querySelector('.markdown-switch-easymde');
- easymdeButton.addEventListener('click', async (e) => {
- e.preventDefault();
- this.userPreferredEditor = 'easymde';
- await this.switchToEasyMDE();
- });
+ if (this.supportEasyMDE) {
+ const easymdeButton = this.container.querySelector('.markdown-switch-easymde');
+ easymdeButton.addEventListener('click', async (e) => {
+ e.preventDefault();
+ this.userPreferredEditor = 'easymde';
+ await this.switchToEasyMDE();
+ });
+ }
this.initMarkdownButtonTableAdd();
@@ -187,6 +200,7 @@ export class ComboMarkdownEditor {
setupTab() {
const tabs = this.container.querySelectorAll<HTMLElement>('.tabular.menu > .item');
+ if (!tabs.length) return;
// Fomantic Tab requires the "data-tab" to be globally unique.
// So here it uses our defined "data-tab-for" and "data-tab-panel" to generate the "data-tab" attribute for Fomantic.
@@ -207,11 +221,8 @@ export class ComboMarkdownEditor {
});
});
- $(tabs).tab();
+ fomanticQuery(tabs).tab();
- this.previewUrl = this.tabPreviewer.getAttribute('data-preview-url');
- this.previewContext = this.tabPreviewer.getAttribute('data-preview-context');
- this.previewMode = this.options.previewMode ?? 'comment';
this.tabPreviewer.addEventListener('click', async () => {
const formData = new FormData();
formData.append('mode', this.previewMode);
@@ -219,7 +230,7 @@ export class ComboMarkdownEditor {
formData.append('text', this.value());
const response = await POST(this.previewUrl, {data: formData});
const data = await response.text();
- renderPreviewPanelContent($(panelPreviewer), data);
+ renderPreviewPanelContent(panelPreviewer, data);
});
}
@@ -284,7 +295,7 @@ export class ComboMarkdownEditor {
}
async switchToUserPreference() {
- if (this.userPreferredEditor === 'easymde') {
+ if (this.userPreferredEditor === 'easymde' && this.supportEasyMDE) {
await this.switchToEasyMDE();
} else {
this.switchToTextarea();
@@ -304,7 +315,7 @@ export class ComboMarkdownEditor {
if (this.easyMDE) return;
// EasyMDE's CSS should be loaded via webpack config, otherwise our own styles can not overwrite the default styles.
const {default: EasyMDE} = await import(/* webpackChunkName: "easymde" */'easymde');
- const easyMDEOpt = {
+ const easyMDEOpt: EasyMDE.Options = {
autoDownloadFontAwesome: false,
element: this.textarea,
forceSync: true,
@@ -384,19 +395,20 @@ export class ComboMarkdownEditor {
}
get userPreferredEditor() {
- return window.localStorage.getItem(`markdown-editor-${this.options.useScene ?? 'default'}`);
+ return window.localStorage.getItem(`markdown-editor-${this.previewMode ?? 'default'}`);
}
set userPreferredEditor(s) {
- window.localStorage.setItem(`markdown-editor-${this.options.useScene ?? 'default'}`, s);
+ window.localStorage.setItem(`markdown-editor-${this.previewMode ?? 'default'}`, s);
}
}
export function getComboMarkdownEditor(el) {
- if (el instanceof $) el = el[0];
- return el?._giteaComboMarkdownEditor;
+ if (!el) return null;
+ if (el.length) el = el[0];
+ return el._giteaComboMarkdownEditor;
}
-export async function initComboMarkdownEditor(container: HTMLElement, options = {}) {
+export async function initComboMarkdownEditor(container: HTMLElement, options:ComboMarkdownEditorOptions = {}) {
if (!container) {
throw new Error('initComboMarkdownEditor: container is null');
}
diff --git a/web_src/js/features/repo-editor.ts b/web_src/js/features/repo-editor.ts
index 6ea9347eba..adae55f25c 100644
--- a/web_src/js/features/repo-editor.ts
+++ b/web_src/js/features/repo-editor.ts
@@ -201,10 +201,8 @@ export function initRepoEditor() {
})();
}
-export function renderPreviewPanelContent($previewPanel, data) {
- $previewPanel.html(data);
+export function renderPreviewPanelContent(previewPanel: Element, content: string) {
+ previewPanel.innerHTML = content;
initMarkupContent();
-
- const $refIssues = $previewPanel.find('p .ref-issue');
- attachRefIssueContextPopup($refIssues);
+ attachRefIssueContextPopup(previewPanel.querySelectorAll('p .ref-issue'));
}
diff --git a/web_src/js/features/repo-issue.ts b/web_src/js/features/repo-issue.ts
index 9cc478712b..a59e4319ab 100644
--- a/web_src/js/features/repo-issue.ts
+++ b/web_src/js/features/repo-issue.ts
@@ -414,11 +414,6 @@ export function initRepoPullRequestReview() {
await handleReply(this);
});
- const elReviewBox = document.querySelector('.review-box-panel');
- if (elReviewBox) {
- initComboMarkdownEditor(elReviewBox.querySelector('.combo-markdown-editor'));
- }
-
// The following part is only for diff views
if (!$('.repository.pull.diff').length) return;
diff --git a/web_src/js/features/repo-release.ts b/web_src/js/features/repo-release.ts
index 7589c77136..c59ab1f323 100644
--- a/web_src/js/features/repo-release.ts
+++ b/web_src/js/features/repo-release.ts
@@ -1,5 +1,4 @@
import {hideElem, showElem} from '../utils/dom.ts';
-import {initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
export function initRepoRelease() {
document.addEventListener('click', (e) => {
@@ -16,7 +15,6 @@ export function initRepoReleaseNew() {
if (!document.querySelector('.repository.new.release')) return;
initTagNameEditor();
- initRepoReleaseEditor();
}
function initTagNameEditor() {
@@ -48,11 +46,3 @@ function initTagNameEditor() {
hideTargetInput(e.target);
});
}
-
-function initRepoReleaseEditor() {
- const editor = document.querySelector<HTMLElement>('.repository.new.release .combo-markdown-editor');
- if (!editor) {
- return;
- }
- initComboMarkdownEditor(editor);
-}
diff --git a/web_src/js/features/repo-wiki.ts b/web_src/js/features/repo-wiki.ts
index 0e72b87109..69188d6ae2 100644
--- a/web_src/js/features/repo-wiki.ts
+++ b/web_src/js/features/repo-wiki.ts
@@ -2,6 +2,7 @@ import {initMarkupContent} from '../markup/content.ts';
import {validateTextareaNonEmpty, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
import {fomanticMobileScreen} from '../modules/fomantic.ts';
import {POST} from '../modules/fetch.ts';
+import type {ComboMarkdownEditor} from './comp/ComboMarkdownEditor.ts';
async function initRepoWikiFormEditor() {
const editArea = document.querySelector<HTMLTextAreaElement>('.repository.wiki .combo-markdown-editor textarea');
@@ -9,7 +10,7 @@ async function initRepoWikiFormEditor() {
const form = document.querySelector('.repository.wiki.new .ui.form');
const editorContainer = form.querySelector<HTMLElement>('.combo-markdown-editor');
- let editor;
+ let editor: ComboMarkdownEditor;
let renderRequesting = false;
let lastContent;
@@ -45,12 +46,10 @@ async function initRepoWikiFormEditor() {
renderEasyMDEPreview();
editor = await initComboMarkdownEditor(editorContainer, {
- useScene: 'wiki',
// EasyMDE has some problems of height definition, it has inline style height 300px by default, so we also use inline styles to override it.
// And another benefit is that we only need to write the style once for both editors.
// TODO: Move height style to CSS after EasyMDE removal.
editorHeights: {minHeight: '300px', height: 'calc(100vh - 600px)'},
- previewMode: 'wiki',
easyMDEOptions: {
previewRender: (_content, previewTarget) => previewTarget.innerHTML, // disable builtin preview render
toolbar: ['bold', 'italic', 'strikethrough', '|',
@@ -59,7 +58,7 @@ async function initRepoWikiFormEditor() {
'unordered-list', 'ordered-list', '|',
'link', 'image', 'table', 'horizontal-rule', '|',
'preview', 'fullscreen', 'side-by-side', '|', 'gitea-switch-to-textarea',
- ],
+ ] as any, // to use custom toolbar buttons
},
});