From c50d8e85dc07c0075eba659b7a89e32136b6d652 Mon Sep 17 00:00:00 2001 From: zadam Date: Sun, 15 May 2022 21:03:51 +0200 Subject: [PATCH] findwidget cleanup --- src/public/app/widgets/find.js | 186 +++++++++++++-------------------- 1 file changed, 71 insertions(+), 115 deletions(-) diff --git a/src/public/app/widgets/find.js b/src/public/app/widgets/find.js index 2ea338797..31769064a 100644 --- a/src/public/app/widgets/find.js +++ b/src/public/app/widgets/find.js @@ -1,32 +1,6 @@ /** - * Find in note replacement for Trilium ctrl+f search * (c) Antonio Tejada 2022 * https://github.com/antoniotejada/Trilium-FindWidget - * - * Features: - * - Find in writeable using ctrl+f and F3 - * - Tested on Trilium Desktop 0.50.3 - * - * Installation: - * - Create a code note of language JS Frontend with the contents of this file - * - Set the owned attributes (alt-a) to #widget - * - Set the owned attributes of any note you don't want to enable finding to - * #noFindWidget - * - Disable Ctrl+f shorcut in Trilium options - * - * Todo: - * - Refactoring/code cleanup - * - Case-sensitive option - * - Regexp option - * - Full word option - * - Find & Replace - * - * Note that many times some common code is replicated between CodeMirror and - * CKEditor codepaths because the CKEditor update is done inside a callback that - * is deferred so the code cannot be put outside of the callback or it will - * execute too early. - * - * See https://github.com/zadam/trilium/discussions/2806 for discussions */ import NoteContextAwareWidget from "./note_context_aware_widget.js"; @@ -44,7 +18,6 @@ const TPL = ` - 0/0 `; @@ -75,76 +48,6 @@ export default class FindWidget extends NoteContextAwareWidget { this.findResult = null; this.needle = null; - // XXX Use api.bindGlobalShortcut? - $(window).keydown(async (e) => { - if ((e.key === 'F3') || - // Note that for ctrl+f to work, needs to be disabled in Trilium's - // shortcut config menu - // XXX Maybe not if using bindShorcut? - ((e.metaKey || e.ctrlKey) && ((e.key === 'f') || (e.key === 'F')))) { - - const note = appContext.tabManager.getActiveContextNote(); - // Only writeable text and code supported - const readOnly = note.getAttribute("label", "readOnly"); - if (!readOnly && (note.type === "code" || note.type === "text")) { - if (this.$findBox.is(":hidden")) { - - this.$findBox.show(); - this.$input.focus(); - this.$numFound.text(0); - this.$curFound.text(0); - - // Initialize the input field to the text selection, if any - if (note.type === "code") { - let codeEditor = getActiveContextCodeEditor(); - - // highlightSelectionMatches is the overlay that highlights - // the words under the cursor. This occludes the search - // markers style, save it, disable it. Will be restored when - // the focus is back into the note - this.oldHighlightSelectionMatches = codeEditor.getOption("highlightSelectionMatches"); - codeEditor.setOption("highlightSelectionMatches", false); - - // Fill in the findbox with the current selection if any - const selectedText = codeEditor.getSelection() - if (selectedText !== "") { - this.$input.val(selectedText); - } - // Directly perform the search if there's some text to find, - // without delaying or waiting for enter - const needle = this.$input.val(); - if (needle !== "") { - this.$input.select(); - await this.performFind(needle); - } - } else { - const textEditor = await getActiveContextTextEditor(); - - const selection = textEditor.model.document.selection; - const range = selection.getFirstRange(); - - for (const item of range.getItems()) { - // Fill in the findbox with the current selection if - // any - this.$input.val(item.data); - break; - } - // Directly perform the search if there's some text to - // find, without delaying or waiting for enter - const needle = this.$input.val(); - if (needle !== "") { - this.$input.select(); - await this.performFind(needle); - } - } - } - e.preventDefault(); - return false; - } - } - return true; - }); - this.$input.keydown(async e => { if ((e.metaKey || e.ctrlKey) && ((e.key === 'F') || (e.key === 'f'))) { // If ctrl+f is pressed when the findbox is shown, select the @@ -173,8 +76,8 @@ export default class FindWidget extends NoteContextAwareWidget { const note = appContext.tabManager.getActiveContextNote(); if (note.type === "code") { - let codeEditor = getActiveContextCodeEditor(); - let doc = codeEditor.doc; + const codeEditor = await getActiveContextCodeEditor(); + const doc = codeEditor.doc; // // Dehighlight current, highlight & scrollIntoView next @@ -216,19 +119,15 @@ export default class FindWidget extends NoteContextAwareWidget { e.preventDefault(); return false; } else if (e.key === 'Escape') { - let numFound = parseInt(this.$numFound.text()); - const note = appContext.tabManager.getActiveContextNote(); if (note.type === "code") { - let codeEditor = getActiveContextCodeEditor(); - + const codeEditor = await getActiveContextCodeEditor(); codeEditor.focus(); } else { const textEditor = await getActiveContextTextEditor(); textEditor.focus(); } } - // e.preventDefault(); }); this.$input.on('input', () => { @@ -275,14 +174,14 @@ export default class FindWidget extends NoteContextAwareWidget { // XXX Switching to a different tab with crl+tab doesn't invoke // blur and leaves a stale search which then breaks when // navigating it - let numFound = parseInt(this.$numFound.text()); - let curFound = parseInt(this.$curFound.text()) - 1; + const numFound = parseInt(this.$numFound.text()); + const curFound = parseInt(this.$curFound.text()) - 1; const note = appContext.tabManager.getActiveContextNote(); if (note.type === "code") { - let codeEditor = await getActiveContextCodeEditor(); + const codeEditor = await getActiveContextCodeEditor(); if (numFound > 0) { - let doc = codeEditor.doc; - let pos = this.findResult[curFound].find(); + const doc = codeEditor.doc; + const pos = this.findResult[curFound].find(); // Note setting the selection sets the cursor to // the end of the selection and scrolls it into // view @@ -305,7 +204,7 @@ export default class FindWidget extends NoteContextAwareWidget { // Clear the markers and set the caret to the // current occurrence const model = textEditor.model; - let range = this.findResult.results.get(curFound).marker.getRange(); + const range = this.findResult.results.get(curFound).marker.getRange(); // From // https://github.com/ckeditor/ckeditor5/blob/b95e2faf817262ac0e1e21993d9c0bde3f1be594/packages/ckeditor5-find-and-replace/src/findandreplace.js#L92 // XXX Roll our own since already done for codeEditor and @@ -329,6 +228,65 @@ export default class FindWidget extends NoteContextAwareWidget { return this.$widget; } + async findInTextEvent() { + const note = appContext.tabManager.getActiveContextNote(); + // Only writeable text and code supported + const readOnly = note.getAttribute("label", "readOnly"); + if (!readOnly && (note.type === "code" || note.type === "text")) { + if (this.$findBox.is(":hidden")) { + + this.$findBox.show(); + this.$input.focus(); + this.$numFound.text(0); + this.$curFound.text(0); + + // Initialize the input field to the text selection, if any + if (note.type === "code") { + const codeEditor = await getActiveContextCodeEditor(); + + // highlightSelectionMatches is the overlay that highlights + // the words under the cursor. This occludes the search + // markers style, save it, disable it. Will be restored when + // the focus is back into the note + this.oldHighlightSelectionMatches = codeEditor.getOption("highlightSelectionMatches"); + codeEditor.setOption("highlightSelectionMatches", false); + + // Fill in the findbox with the current selection if any + const selectedText = codeEditor.getSelection() + if (selectedText !== "") { + this.$input.val(selectedText); + } + // Directly perform the search if there's some text to find, + // without delaying or waiting for enter + const needle = this.$input.val(); + if (needle !== "") { + this.$input.select(); + await this.performFind(needle); + } + } else { + const textEditor = await getActiveContextTextEditor(); + + const selection = textEditor.model.document.selection; + const range = selection.getFirstRange(); + + for (const item of range.getItems()) { + // Fill in the findbox with the current selection if + // any + this.$input.val(item.data); + break; + } + // Directly perform the search if there's some text to + // find, without delaying or waiting for enter + const needle = this.$input.val(); + if (needle !== "") { + this.$input.select(); + await this.performFind(needle); + } + } + } + } + } + async performTextNoteFind(needle, matchCase, wholeWord) { // Do this even if the needle is empty so the markers are cleared and // the counters updated @@ -403,7 +361,7 @@ export default class FindWidget extends NoteContextAwareWidget { }); } - if (needle != "") { + if (needle !== "") { needle = escapeRegExp(needle); // Find and highlight matches @@ -451,7 +409,7 @@ export default class FindWidget extends NoteContextAwareWidget { if (curFound === -1) { const cursorPos = codeEditor.getCursor(); if ((fromPos.line > cursorPos.line) || - ((fromPos.line == cursorPos.line) && + ((fromPos.line === cursorPos.line) && (fromPos.ch >= cursorPos.ch))){ curFound = numFound; } @@ -510,9 +468,7 @@ export default class FindWidget extends NoteContextAwareWidget { } isEnabled() { - return super.isEnabled() - && ((this.note.type === 'text') || (this.note.type === 'code')) - && !this.note.hasLabel('noFindWidget'); + return super.isEnabled() && (this.note.type === 'text' || this.note.type === 'code'); } async entitiesReloadedEvent({loadResults}) {