mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-08-07 23:03:00 +03:00
Comments: Switched to lexical editor
Required a lot of changes to provide at least a decent attempt at proper editor teardown control. Also updates HtmlDescriptionFilter and testing to address issue with bad child iteration which could lead to missed items. Renamed editor version from comments to basic as it'll also be used for item descriptions.
This commit is contained in:
@@ -12,6 +12,8 @@ export type SelectionChangeHandler = (selection: BaseSelection|null) => void;
|
||||
|
||||
export class EditorUIManager {
|
||||
|
||||
public dropdowns: DropDownManager = new DropDownManager();
|
||||
|
||||
protected modalDefinitionsByKey: Record<string, EditorFormModalDefinition> = {};
|
||||
protected activeModalsByKey: Record<string, EditorFormModal> = {};
|
||||
protected decoratorConstructorsByType: Record<string, typeof EditorDecorator> = {};
|
||||
@@ -21,12 +23,12 @@ export class EditorUIManager {
|
||||
protected contextToolbarDefinitionsByKey: Record<string, EditorContextToolbarDefinition> = {};
|
||||
protected activeContextToolbars: EditorContextToolbar[] = [];
|
||||
protected selectionChangeHandlers: Set<SelectionChangeHandler> = new Set();
|
||||
|
||||
public dropdowns: DropDownManager = new DropDownManager();
|
||||
protected domEventAbortController = new AbortController();
|
||||
protected teardownCallbacks: (()=>void)[] = [];
|
||||
|
||||
setContext(context: EditorUiContext) {
|
||||
this.context = context;
|
||||
this.setupEventListeners(context);
|
||||
this.setupEventListeners();
|
||||
this.setupEditor(context.editor);
|
||||
}
|
||||
|
||||
@@ -99,7 +101,7 @@ export class EditorUIManager {
|
||||
|
||||
setToolbar(toolbar: EditorContainerUiElement) {
|
||||
if (this.toolbar) {
|
||||
this.toolbar.getDOMElement().remove();
|
||||
this.toolbar.teardown();
|
||||
}
|
||||
|
||||
this.toolbar = toolbar;
|
||||
@@ -170,10 +172,40 @@ export class EditorUIManager {
|
||||
return this.getContext().options.textDirection === 'rtl' ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
onTeardown(callback: () => void): void {
|
||||
this.teardownCallbacks.push(callback);
|
||||
}
|
||||
|
||||
teardown(): void {
|
||||
this.domEventAbortController.abort('teardown');
|
||||
|
||||
for (const [_, modal] of Object.entries(this.activeModalsByKey)) {
|
||||
modal.teardown();
|
||||
}
|
||||
|
||||
for (const [_, decorator] of Object.entries(this.decoratorInstancesByNodeKey)) {
|
||||
decorator.teardown();
|
||||
}
|
||||
|
||||
if (this.toolbar) {
|
||||
this.toolbar.teardown();
|
||||
}
|
||||
|
||||
for (const toolbar of this.activeContextToolbars) {
|
||||
toolbar.teardown();
|
||||
}
|
||||
|
||||
this.dropdowns.teardown();
|
||||
|
||||
for (const callback of this.teardownCallbacks) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
protected updateContextToolbars(update: EditorUiStateUpdate): void {
|
||||
for (let i = this.activeContextToolbars.length - 1; i >= 0; i--) {
|
||||
const toolbar = this.activeContextToolbars[i];
|
||||
toolbar.destroy();
|
||||
toolbar.teardown();
|
||||
this.activeContextToolbars.splice(i, 1);
|
||||
}
|
||||
|
||||
@@ -253,9 +285,9 @@ export class EditorUIManager {
|
||||
});
|
||||
}
|
||||
|
||||
protected setupEventListeners(context: EditorUiContext) {
|
||||
protected setupEventListeners() {
|
||||
const layoutUpdate = this.triggerLayoutUpdate.bind(this);
|
||||
window.addEventListener('scroll', layoutUpdate, {capture: true, passive: true});
|
||||
window.addEventListener('resize', layoutUpdate, {passive: true});
|
||||
window.addEventListener('scroll', layoutUpdate, {capture: true, passive: true, signal: this.domEventAbortController.signal});
|
||||
window.addEventListener('resize', layoutUpdate, {passive: true, signal: this.domEventAbortController.signal});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user