protection against text note initialization race conditions

This commit is contained in:
zadam 2020-01-07 19:48:26 +01:00
parent f0dfe7d552
commit 24c5388e0c
2 changed files with 43 additions and 42 deletions

View file

@ -201,17 +201,13 @@ async function loadNoteDetail(origNotePath, options = {}) {
const newTab = !!options.newTab; const newTab = !!options.newTab;
const activate = !!options.activate; const activate = !!options.activate;
const notePath = await treeService.resolveNotePath(origNotePath); let notePath = await treeService.resolveNotePath(origNotePath);
if (!notePath) { if (!notePath) {
console.error(`Cannot resolve note path ${origNotePath}`); console.error(`Cannot resolve note path ${origNotePath}`);
// fallback to display something // fallback to display something
if (tabContexts.length === 0) { notePath = 'root';
await openEmptyTab();
}
return;
} }
const noteId = treeUtils.getNoteIdFromNotePath(notePath); const noteId = treeUtils.getNoteIdFromNotePath(notePath);

View file

@ -47,6 +47,7 @@ class NoteDetailText {
this.ctx = ctx; this.ctx = ctx;
this.$component = ctx.$tabContent.find('.note-detail-text'); this.$component = ctx.$tabContent.find('.note-detail-text');
this.$editorEl = this.$component.find('.note-detail-text-editor'); this.$editorEl = this.$component.find('.note-detail-text-editor');
this.textEditorPromise = null;
this.textEditor = null; this.textEditor = null;
this.$component.on("dblclick", "img", e => { this.$component.on("dblclick", "img", e => {
@ -67,7 +68,23 @@ class NoteDetailText {
} }
async render() { async render() {
if (!this.textEditor) { if (!this.textEditorPromise) {
this.textEditorPromise = this.initEditor();
}
await this.textEditorPromise;
// lazy loading above can take time and tab might have been already switched to another note
if (this.ctx.note && this.ctx.note.type === 'text') {
this.textEditor.isReadOnly = await this.isReadOnly();
this.$component.show();
this.textEditor.setData(this.ctx.note.content);
}
}
async initEditor() {
await libraryLoader.requireLibrary(libraryLoader.CKEDITOR); await libraryLoader.requireLibrary(libraryLoader.CKEDITOR);
const codeBlockLanguages = const codeBlockLanguages =
@ -85,10 +102,7 @@ class NoteDetailText {
// display of $component in both branches. // display of $component in both branches.
this.$component.show(); this.$component.show();
// textEditor might have been initialized during previous await so checking again const textEditorInstance = await BalloonEditor.create(this.$editorEl[0], {
// looks like double initialization can freeze CKEditor pretty badly
if (!this.textEditor) {
this.textEditor = await BalloonEditor.create(this.$editorEl[0], {
placeholder: "Type the content of your note here ...", placeholder: "Type the content of your note here ...",
mention: mentionSetup, mention: mentionSetup,
codeBlock: { codeBlock: {
@ -98,22 +112,13 @@ class NoteDetailText {
if (glob.isDev && ENABLE_INSPECTOR) { if (glob.isDev && ENABLE_INSPECTOR) {
await import('../../libraries/ckeditor/inspector.js'); await import('../../libraries/ckeditor/inspector.js');
CKEditorInspector.attach(this.textEditor); CKEditorInspector.attach(textEditorInstance);
} }
this.textEditor = textEditorInstance;
this.onNoteChange(() => this.ctx.noteChanged()); this.onNoteChange(() => this.ctx.noteChanged());
} }
}
// lazy loading above can take time and tab might have been already switched to another note
if (this.ctx.note && this.ctx.note.type === 'text') {
this.textEditor.isReadOnly = await this.isReadOnly();
this.$component.show();
this.textEditor.setData(this.ctx.note.content);
}
}
getContent() { getContent() {
const content = this.textEditor.getData(); const content = this.textEditor.getData();