diff --git a/src/public/javascripts/services/note_detail.js b/src/public/javascripts/services/note_detail.js index b17bb7d61..ed7a03474 100644 --- a/src/public/javascripts/services/note_detail.js +++ b/src/public/javascripts/services/note_detail.js @@ -201,17 +201,13 @@ async function loadNoteDetail(origNotePath, options = {}) { const newTab = !!options.newTab; const activate = !!options.activate; - const notePath = await treeService.resolveNotePath(origNotePath); + let notePath = await treeService.resolveNotePath(origNotePath); if (!notePath) { console.error(`Cannot resolve note path ${origNotePath}`); // fallback to display something - if (tabContexts.length === 0) { - await openEmptyTab(); - } - - return; + notePath = 'root'; } const noteId = treeUtils.getNoteIdFromNotePath(notePath); diff --git a/src/public/javascripts/services/note_detail_text.js b/src/public/javascripts/services/note_detail_text.js index d81d5aed0..ab48e7e1a 100644 --- a/src/public/javascripts/services/note_detail_text.js +++ b/src/public/javascripts/services/note_detail_text.js @@ -47,6 +47,7 @@ class NoteDetailText { this.ctx = ctx; this.$component = ctx.$tabContent.find('.note-detail-text'); this.$editorEl = this.$component.find('.note-detail-text-editor'); + this.textEditorPromise = null; this.textEditor = null; this.$component.on("dblclick", "img", e => { @@ -67,44 +68,12 @@ class NoteDetailText { } async render() { - if (!this.textEditor) { - await libraryLoader.requireLibrary(libraryLoader.CKEDITOR); - - const codeBlockLanguages = - (await mimeTypesService.getMimeTypes()) - .filter(mt => mt.enabled) - .map(mt => { - return { - language: mt.mime.toLowerCase().replace(/[\W_]+/g,"-"), - label: mt.title - } - }); - - // CKEditor since version 12 needs the element to be visible before initialization. At the same time - // we want to avoid flicker - i.e. show editor only once everything is ready. That's why we have separate - // display of $component in both branches. - this.$component.show(); - - // textEditor might have been initialized during previous await so checking again - // 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 ...", - mention: mentionSetup, - codeBlock: { - languages: codeBlockLanguages - } - }); - - if (glob.isDev && ENABLE_INSPECTOR) { - await import('../../libraries/ckeditor/inspector.js'); - CKEditorInspector.attach(this.textEditor); - } - - this.onNoteChange(() => this.ctx.noteChanged()); - } + 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(); @@ -115,6 +84,42 @@ class NoteDetailText { } } + async initEditor() { + await libraryLoader.requireLibrary(libraryLoader.CKEDITOR); + + const codeBlockLanguages = + (await mimeTypesService.getMimeTypes()) + .filter(mt => mt.enabled) + .map(mt => { + return { + language: mt.mime.toLowerCase().replace(/[\W_]+/g,"-"), + label: mt.title + } + }); + + // CKEditor since version 12 needs the element to be visible before initialization. At the same time + // we want to avoid flicker - i.e. show editor only once everything is ready. That's why we have separate + // display of $component in both branches. + this.$component.show(); + + const textEditorInstance = await BalloonEditor.create(this.$editorEl[0], { + placeholder: "Type the content of your note here ...", + mention: mentionSetup, + codeBlock: { + languages: codeBlockLanguages + } + }); + + if (glob.isDev && ENABLE_INSPECTOR) { + await import('../../libraries/ckeditor/inspector.js'); + CKEditorInspector.attach(textEditorInstance); + } + + this.textEditor = textEditorInstance; + + this.onNoteChange(() => this.ctx.noteChanged()); + } + getContent() { const content = this.textEditor.getData();