mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-28 17:02:04 +03:00
Merge pull request #5676 from BookStackApp/lexical_comments
New WYSIWYG editor for comments & descriptions
This commit is contained in:
@ -1,8 +1,9 @@
|
||||
import {Component} from './component';
|
||||
import {getLoading, htmlToDom} from '../services/dom';
|
||||
import {buildForInput} from '../wysiwyg-tinymce/config';
|
||||
import {PageCommentReference} from "./page-comment-reference";
|
||||
import {HttpError} from "../services/http";
|
||||
import {SimpleWysiwygEditorInterface} from "../wysiwyg";
|
||||
import {el} from "../wysiwyg/utils/dom";
|
||||
|
||||
export interface PageCommentReplyEventData {
|
||||
id: string; // ID of comment being replied to
|
||||
@ -21,8 +22,7 @@ export class PageComment extends Component {
|
||||
protected updatedText!: string;
|
||||
protected archiveText!: string;
|
||||
|
||||
protected wysiwygEditor: any = null;
|
||||
protected wysiwygLanguage!: string;
|
||||
protected wysiwygEditor: SimpleWysiwygEditorInterface|null = null;
|
||||
protected wysiwygTextDirection!: string;
|
||||
|
||||
protected container!: HTMLElement;
|
||||
@ -44,7 +44,6 @@ export class PageComment extends Component {
|
||||
this.archiveText = this.$opts.archiveText;
|
||||
|
||||
// Editor reference and text options
|
||||
this.wysiwygLanguage = this.$opts.wysiwygLanguage;
|
||||
this.wysiwygTextDirection = this.$opts.wysiwygTextDirection;
|
||||
|
||||
// Element references
|
||||
@ -90,7 +89,7 @@ export class PageComment extends Component {
|
||||
this.form.toggleAttribute('hidden', !show);
|
||||
}
|
||||
|
||||
protected startEdit() : void {
|
||||
protected async startEdit(): Promise<void> {
|
||||
this.toggleEditMode(true);
|
||||
|
||||
if (this.wysiwygEditor) {
|
||||
@ -98,21 +97,20 @@ export class PageComment extends Component {
|
||||
return;
|
||||
}
|
||||
|
||||
const config = buildForInput({
|
||||
language: this.wysiwygLanguage,
|
||||
containerElement: this.input,
|
||||
type WysiwygModule = typeof import('../wysiwyg');
|
||||
const wysiwygModule = (await window.importVersioned('wysiwyg')) as WysiwygModule;
|
||||
const editorContent = this.input.value;
|
||||
const container = el('div', {class: 'comment-editor-container'});
|
||||
this.input.parentElement?.appendChild(container);
|
||||
this.input.hidden = true;
|
||||
|
||||
this.wysiwygEditor = wysiwygModule.createBasicEditorInstance(container as HTMLElement, editorContent, {
|
||||
darkMode: document.documentElement.classList.contains('dark-mode'),
|
||||
textDirection: this.wysiwygTextDirection,
|
||||
drawioUrl: '',
|
||||
pageId: 0,
|
||||
translations: {},
|
||||
translationMap: (window as unknown as Record<string, Object>).editor_translations,
|
||||
textDirection: this.$opts.textDirection,
|
||||
translations: (window as unknown as Record<string, Object>).editor_translations,
|
||||
});
|
||||
|
||||
(window as unknown as {tinymce: {init: (arg0: Object) => Promise<any>}}).tinymce.init(config).then(editors => {
|
||||
this.wysiwygEditor = editors[0];
|
||||
setTimeout(() => this.wysiwygEditor.focus(), 50);
|
||||
});
|
||||
this.wysiwygEditor.focus();
|
||||
}
|
||||
|
||||
protected async update(event: Event): Promise<void> {
|
||||
@ -121,7 +119,7 @@ export class PageComment extends Component {
|
||||
this.form.toggleAttribute('hidden', true);
|
||||
|
||||
const reqData = {
|
||||
html: this.wysiwygEditor.getContent(),
|
||||
html: await this.wysiwygEditor?.getContentAsHtml() || '',
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import {Component} from './component';
|
||||
import {getLoading, htmlToDom} from '../services/dom';
|
||||
import {buildForInput} from '../wysiwyg-tinymce/config';
|
||||
import {Tabs} from "./tabs";
|
||||
import {PageCommentReference} from "./page-comment-reference";
|
||||
import {scrollAndHighlightElement} from "../services/util";
|
||||
import {PageCommentArchiveEventData, PageCommentReplyEventData} from "./page-comment";
|
||||
import {el} from "../wysiwyg/utils/dom";
|
||||
import {SimpleWysiwygEditorInterface} from "../wysiwyg";
|
||||
|
||||
export class PageComments extends Component {
|
||||
|
||||
@ -28,9 +29,8 @@ export class PageComments extends Component {
|
||||
private hideFormButton!: HTMLElement;
|
||||
private removeReplyToButton!: HTMLElement;
|
||||
private removeReferenceButton!: HTMLElement;
|
||||
private wysiwygLanguage!: string;
|
||||
private wysiwygTextDirection!: string;
|
||||
private wysiwygEditor: any = null;
|
||||
private wysiwygEditor: SimpleWysiwygEditorInterface|null = null;
|
||||
private createdText!: string;
|
||||
private countText!: string;
|
||||
private archivedCountText!: string;
|
||||
@ -63,7 +63,6 @@ export class PageComments extends Component {
|
||||
this.removeReferenceButton = this.$refs.removeReferenceButton;
|
||||
|
||||
// WYSIWYG options
|
||||
this.wysiwygLanguage = this.$opts.wysiwygLanguage;
|
||||
this.wysiwygTextDirection = this.$opts.wysiwygTextDirection;
|
||||
|
||||
// Translations
|
||||
@ -107,7 +106,7 @@ export class PageComments extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
protected saveComment(event: SubmitEvent): void {
|
||||
protected async saveComment(event: SubmitEvent): Promise<void> {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
@ -117,7 +116,7 @@ export class PageComments extends Component {
|
||||
this.form.toggleAttribute('hidden', true);
|
||||
|
||||
const reqData = {
|
||||
html: this.wysiwygEditor.getContent(),
|
||||
html: (await this.wysiwygEditor?.getContentAsHtml()) || '',
|
||||
parent_id: this.parentId || null,
|
||||
content_ref: this.contentReference,
|
||||
};
|
||||
@ -189,27 +188,25 @@ export class PageComments extends Component {
|
||||
this.addButtonContainer.toggleAttribute('hidden', false);
|
||||
}
|
||||
|
||||
protected loadEditor(): void {
|
||||
protected async loadEditor(): Promise<void> {
|
||||
if (this.wysiwygEditor) {
|
||||
this.wysiwygEditor.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
const config = buildForInput({
|
||||
language: this.wysiwygLanguage,
|
||||
containerElement: this.formInput,
|
||||
type WysiwygModule = typeof import('../wysiwyg');
|
||||
const wysiwygModule = (await window.importVersioned('wysiwyg')) as WysiwygModule;
|
||||
const container = el('div', {class: 'comment-editor-container'});
|
||||
this.formInput.parentElement?.appendChild(container);
|
||||
this.formInput.hidden = true;
|
||||
|
||||
this.wysiwygEditor = wysiwygModule.createBasicEditorInstance(container as HTMLElement, '<p></p>', {
|
||||
darkMode: document.documentElement.classList.contains('dark-mode'),
|
||||
textDirection: this.wysiwygTextDirection,
|
||||
drawioUrl: '',
|
||||
pageId: 0,
|
||||
translations: {},
|
||||
translationMap: (window as unknown as Record<string, Object>).editor_translations,
|
||||
translations: (window as unknown as Record<string, Object>).editor_translations,
|
||||
});
|
||||
|
||||
(window as unknown as {tinymce: {init: (arg0: Object) => Promise<any>}}).tinymce.init(config).then(editors => {
|
||||
this.wysiwygEditor = editors[0];
|
||||
setTimeout(() => this.wysiwygEditor.focus(), 50);
|
||||
});
|
||||
this.wysiwygEditor.focus();
|
||||
}
|
||||
|
||||
protected removeEditor(): void {
|
||||
|
@ -1,23 +0,0 @@
|
||||
import {Component} from './component';
|
||||
import {buildForInput} from '../wysiwyg-tinymce/config';
|
||||
|
||||
export class WysiwygInput extends Component {
|
||||
|
||||
setup() {
|
||||
this.elem = this.$el;
|
||||
|
||||
const config = buildForInput({
|
||||
language: this.$opts.language,
|
||||
containerElement: this.elem,
|
||||
darkMode: document.documentElement.classList.contains('dark-mode'),
|
||||
textDirection: this.$opts.textDirection,
|
||||
translations: {},
|
||||
translationMap: window.editor_translations,
|
||||
});
|
||||
|
||||
window.tinymce.init(config).then(editors => {
|
||||
this.editor = editors[0];
|
||||
});
|
||||
}
|
||||
|
||||
}
|
32
resources/js/components/wysiwyg-input.ts
Normal file
32
resources/js/components/wysiwyg-input.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import {Component} from './component';
|
||||
import {el} from "../wysiwyg/utils/dom";
|
||||
import {SimpleWysiwygEditorInterface} from "../wysiwyg";
|
||||
|
||||
export class WysiwygInput extends Component {
|
||||
private elem!: HTMLTextAreaElement;
|
||||
private wysiwygEditor!: SimpleWysiwygEditorInterface;
|
||||
private textDirection!: string;
|
||||
|
||||
async setup() {
|
||||
this.elem = this.$el as HTMLTextAreaElement;
|
||||
this.textDirection = this.$opts.textDirection;
|
||||
|
||||
type WysiwygModule = typeof import('../wysiwyg');
|
||||
const wysiwygModule = (await window.importVersioned('wysiwyg')) as WysiwygModule;
|
||||
const container = el('div', {class: 'basic-editor-container'});
|
||||
this.elem.parentElement?.appendChild(container);
|
||||
this.elem.hidden = true;
|
||||
|
||||
this.wysiwygEditor = wysiwygModule.createBasicEditorInstance(container as HTMLElement, this.elem.value, {
|
||||
darkMode: document.documentElement.classList.contains('dark-mode'),
|
||||
textDirection: this.textDirection,
|
||||
translations: (window as unknown as Record<string, Object>).editor_translations,
|
||||
});
|
||||
|
||||
this.wysiwygEditor.onChange(() => {
|
||||
this.wysiwygEditor.getContentAsHtml().then(html => {
|
||||
this.elem.value = html;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user