diff --git a/src/public/app/dialogs/markdown_import.js b/src/public/app/dialogs/markdown_import.js index e83522cf7..94712b28e 100644 --- a/src/public/app/dialogs/markdown_import.js +++ b/src/public/app/dialogs/markdown_import.js @@ -16,7 +16,7 @@ async function convertMarkdownToHtml(text) { const result = writer.render(parsed); - appContext.triggerCommand('executeInActiveTextEditor', { + appContext.triggerCommand('executeInTextEditor', { callback: textEditor => { const viewFragment = textEditor.data.processor.toView(result); const modelFragment = textEditor.data.toModel(viewFragment); @@ -24,7 +24,8 @@ async function convertMarkdownToHtml(text) { textEditor.model.insertContent(modelFragment, textEditor.model.document.selection); toastService.showMessage("Markdown content has been imported into the document."); - } + }, + ntxId: this.ntxId }); } diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js index dee3b7a7d..b2eabdc13 100644 --- a/src/public/app/services/frontend_script_api.js +++ b/src/public/app/services/frontend_script_api.js @@ -384,7 +384,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain this.getActiveTabTextEditor = callback => { console.warn("api.getActiveTabTextEditor() is deprecated, use getActiveContextTextEditor() instead."); - return appContext.tabManager.getActiveContextTextEditor(callback); + return appContext.tabManager.getActiveContext()?.getTextEditor(callback); }; /** @@ -393,7 +393,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * @method * @returns {Promise} instance of CKEditor */ - this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContextTextEditor(); + this.getActiveContextTextEditor = () => appContext.tabManager.getActiveContext()?.getTextEditor(); /** * See https://codemirror.net/doc/manual.html#api @@ -401,7 +401,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain * @method * @returns {Promise} instance of CodeMirror */ - this.getActiveContextCodeEditor = () => appContext.tabManager.getActiveContextCodeEditor(); + this.getActiveContextCodeEditor = () => appContext.tabManager.getActiveContext()?.getCodeEditor(); /** * Get access to the widget handling note detail. Methods like `getWidgetType()` and `getTypeWidget()` to get to the diff --git a/src/public/app/services/note_context.js b/src/public/app/services/note_context.js index 2b7e71fa3..179fd1aea 100644 --- a/src/public/app/services/note_context.js +++ b/src/public/app/services/note_context.js @@ -226,6 +226,21 @@ class NoteContext extends Component { && this.note.mime !== 'text/x-sqlite;schema=trilium' && !this.note.hasLabel('hideChildrenOverview'); } + + async getTextEditor(callback) { + return new Promise(resolve => appContext.triggerCommand('executeInTextEditor', { + callback, + resolve, + ntxId: this.ntxId + })); + } + + async getCodeEditor() { + return new Promise(resolve => appContext.triggerCommand('executeInCodeEditor', { + resolve, + ntxId: this.ntxId + })); + } } export default NoteContext; diff --git a/src/public/app/services/tab_manager.js b/src/public/app/services/tab_manager.js index 1250b6948..15f939bfe 100644 --- a/src/public/app/services/tab_manager.js +++ b/src/public/app/services/tab_manager.js @@ -193,14 +193,6 @@ export default class TabManager extends Component { return activeNote ? activeNote.type : null; } - async getActiveContextTextEditor(callback) { - return new Promise(resolve => appContext.triggerCommand('executeInActiveTextEditor', {callback, resolve})); - } - - async getActiveContextCodeEditor() { - return new Promise(resolve => appContext.triggerCommand('executeInActiveCodeEditor', {resolve})); - } - async switchToNoteContext(ntxId, notePath) { const noteContext = this.noteContexts.find(nc => nc.ntxId === ntxId) || await this.openEmptyTab(); diff --git a/src/public/app/widgets/find.js b/src/public/app/widgets/find.js index 0e5ad3b7a..9e0590ce9 100644 --- a/src/public/app/widgets/find.js +++ b/src/public/app/widgets/find.js @@ -78,8 +78,8 @@ export default class FindWidget extends NoteContextAwareWidget { this.searchTerm = null; - this.textHandler = new FindInText(); - this.codeHandler = new FindInCode(); + this.textHandler = new FindInText(this); + this.codeHandler = new FindInCode(this); } doRender() { @@ -155,11 +155,15 @@ export default class FindWidget extends NoteContextAwareWidget { this.$currentFound.text(nextFound + 1); - await this.getHandler().findNext(direction, currentFound, nextFound); + await this.handler.findNext(direction, currentFound, nextFound); } } async findInTextEvent() { + if (!this.isActiveNoteContext()) { + return; + } + // Only writeable text and code supported const readOnly = await this.noteContext.isReadOnly(); @@ -172,7 +176,7 @@ export default class FindWidget extends NoteContextAwareWidget { this.$totalFound.text(0); this.$currentFound.text(0); - const searchTerm = await this.getHandler().getInitialSearchTerm(); + const searchTerm = await this.handler.getInitialSearchTerm(); this.$input.val(searchTerm || ""); @@ -190,7 +194,7 @@ export default class FindWidget extends NoteContextAwareWidget { const matchCase = this.$caseSensitiveCheckbox.prop("checked"); const wholeWord = this.$matchWordsCheckbox.prop("checked"); - const {totalFound, currentFound} = await this.getHandler().performFind(searchTerm, matchCase, wholeWord); + const {totalFound, currentFound} = await this.handler.performFind(searchTerm, matchCase, wholeWord); this.$totalFound.text(totalFound); this.$currentFound.text(currentFound); @@ -207,7 +211,7 @@ export default class FindWidget extends NoteContextAwareWidget { const currentFound = parseInt(this.$currentFound.text()) - 1; if (totalFound > 0) { - await this.getHandler().cleanup(totalFound, currentFound); + await this.handler.cleanup(totalFound, currentFound); } this.searchTerm = null; @@ -223,7 +227,7 @@ export default class FindWidget extends NoteContextAwareWidget { return super.isEnabled() && ['text', 'code'].includes(this.note.type); } - getHandler() { + get handler() { return this.note.type === "code" ? this.codeHandler : this.textHandler; diff --git a/src/public/app/widgets/find_in_code.js b/src/public/app/widgets/find_in_code.js index 764f42f9b..7a6bcbced 100644 --- a/src/public/app/widgets/find_in_code.js +++ b/src/public/app/widgets/find_in_code.js @@ -1,17 +1,22 @@ -import appContext from "../services/app_context.js"; - // ck-find-result and ck-find-result_selected are the styles ck-editor // uses for highlighting matches, use the same one on CodeMirror // for consistency const FIND_RESULT_SELECTED_CSS_CLASSNAME = "ck-find-result_selected"; const FIND_RESULT_CSS_CLASSNAME = "ck-find-result"; -const getActiveContextCodeEditor = async () => await appContext.tabManager.getActiveContextCodeEditor(); const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); export default class FindInCode { + constructor(parent) { + this.parent = parent; + } + + async getCodeEditor() { + return this.parent.noteContext.getCodeEditor(); + } + async getInitialSearchTerm() { - const codeEditor = await getActiveContextCodeEditor(); + const codeEditor = await this.getCodeEditor(); // highlightSelectionMatches is the overlay that highlights // the words under the cursor. This occludes the search @@ -33,7 +38,7 @@ export default class FindInCode { let currentFound = -1; // See https://codemirror.net/addon/search/searchcursor.js for tips - const codeEditor = await getActiveContextCodeEditor(); + const codeEditor = await this.getCodeEditor(); const doc = codeEditor.doc; const text = doc.getValue(); @@ -135,7 +140,7 @@ export default class FindInCode { } async findNext(direction, currentFound, nextFound) { - const codeEditor = await getActiveContextCodeEditor(); + const codeEditor = await this.getCodeEditor(); const doc = codeEditor.doc; // @@ -164,7 +169,7 @@ export default class FindInCode { } async cleanup(totalFound, currentFound) { - const codeEditor = await getActiveContextCodeEditor(); + const codeEditor = await this.getCodeEditor(); if (totalFound > 0) { const doc = codeEditor.doc; @@ -187,7 +192,7 @@ export default class FindInCode { } async close() { - const codeEditor = await getActiveContextCodeEditor(); + const codeEditor = await this.getCodeEditor(); codeEditor.focus(); } } diff --git a/src/public/app/widgets/find_in_text.js b/src/public/app/widgets/find_in_text.js index 5db1a8b63..54f3bd091 100644 --- a/src/public/app/widgets/find_in_text.js +++ b/src/public/app/widgets/find_in_text.js @@ -1,10 +1,14 @@ -import appContext from "../services/app_context.js"; - -const getActiveContextTextEditor = async () => await appContext.tabManager.getActiveContextTextEditor(); - export default class FindInText { + constructor(parent) { + this.parent = parent; + } + + async getTextEditor() { + return this.parent.noteContext.getTextEditor(); + } + async getInitialSearchTerm() { - const textEditor = await getActiveContextTextEditor(); + const textEditor = await this.getTextEditor(); const selection = textEditor.model.document.selection; const range = selection.getFirstRange(); @@ -19,7 +23,7 @@ export default class FindInText { async performFind(searchTerm, matchCase, wholeWord) { // Do this even if the searchTerm is empty so the markers are cleared and // the counters updated - const textEditor = await getActiveContextTextEditor(); + const textEditor = await this.getTextEditor(); const model = textEditor.model; let findResult = null; let totalFound = 0; @@ -73,7 +77,7 @@ export default class FindInText { } async findNext(direction, currentFound, nextFound) { - const textEditor = await getActiveContextTextEditor(); + const textEditor = await this.getTextEditor(); // There are no parameters for findNext/findPrev // See https://github.com/ckeditor/ckeditor5/blob/b95e2faf817262ac0e1e21993d9c0bde3f1be594/packages/ckeditor5-find-and-replace/src/findnextcommand.js#L57 @@ -88,7 +92,7 @@ export default class FindInText { async cleanup(totalFound, currentFound) { if (totalFound > 0) { - const textEditor = await getActiveContextTextEditor(); + const textEditor = await this.getTextEditor(); // Clear the markers and set the caret to the // current occurrence const model = textEditor.model; @@ -110,7 +114,7 @@ export default class FindInText { } async close() { - const textEditor = await getActiveContextTextEditor(); + const textEditor = await this.getTextEditor(); textEditor.focus(); } } diff --git a/src/public/app/widgets/type_widgets/editable_code.js b/src/public/app/widgets/type_widgets/editable_code.js index afffd9e8a..2a4097f1c 100644 --- a/src/public/app/widgets/type_widgets/editable_code.js +++ b/src/public/app/widgets/type_widgets/editable_code.js @@ -171,8 +171,8 @@ export default class EditableCodeTypeWidget extends TypeWidget { } } - async executeInActiveCodeEditorEvent({resolve}) { - if (!this.isActive()) { + async executeInCodeEditorEvent({resolve, ntxId}) { + if (!this.isNoteContext(ntxId)) { return; } diff --git a/src/public/app/widgets/type_widgets/editable_text.js b/src/public/app/widgets/type_widgets/editable_text.js index 44469fdc6..f51138289 100644 --- a/src/public/app/widgets/type_widgets/editable_text.js +++ b/src/public/app/widgets/type_widgets/editable_text.js @@ -229,8 +229,8 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget { return !selection.isCollapsed; } - async executeInActiveTextEditorEvent({callback, resolve}) { - if (!this.isActive()) { + async executeInTextEditorEvent({callback, resolve, ntxId}) { + if (!this.isNoteContext(ntxId)) { return; }