mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 04:51:31 +08:00 
			
		
		
		
	Merge pull request #1876 from TriliumNext/find_replace
Make the find function for read-only code scroll correctly.
This commit is contained in:
		
						commit
						307d94a5df
					
				| @ -438,6 +438,14 @@ body .CodeMirror { | ||||
|     background-color: #eeeeee; | ||||
| } | ||||
| 
 | ||||
| .cm-matchhighlight.ck-find-result{ | ||||
|     background: var(--ck-color-highlight-background); | ||||
| } | ||||
| 
 | ||||
| .cm-matchhighlight.ck-find-result_selected { | ||||
|     background-color: #ff9633; | ||||
| } | ||||
| 
 | ||||
| .CodeMirror pre.CodeMirror-placeholder { | ||||
|     color: #999 !important; | ||||
| } | ||||
|  | ||||
| @ -143,9 +143,9 @@ export default class FindWidget extends NoteContextAwareWidget { | ||||
|         this.$currentFound = this.$widget.find(".find-widget-current-found"); | ||||
|         this.$totalFound = this.$widget.find(".find-widget-total-found"); | ||||
|         this.$caseSensitiveCheckbox = this.$widget.find(".find-widget-case-sensitive-checkbox"); | ||||
|         this.$caseSensitiveCheckbox.change(() => this.performFind()); | ||||
|         this.$caseSensitiveCheckbox.on("change", () => this.performFind()); | ||||
|         this.$matchWordsCheckbox = this.$widget.find(".find-widget-match-words-checkbox"); | ||||
|         this.$matchWordsCheckbox.change(() => this.performFind()); | ||||
|         this.$matchWordsCheckbox.on("change", () => this.performFind()); | ||||
|         this.$previousButton = this.$widget.find(".find-widget-previous-button"); | ||||
|         this.$previousButton.on("click", () => this.findNext(-1)); | ||||
|         this.$nextButton = this.$widget.find(".find-widget-next-button"); | ||||
| @ -160,7 +160,7 @@ export default class FindWidget extends NoteContextAwareWidget { | ||||
|         this.$replaceButton = this.$widget.find(".replace-widget-replace-button"); | ||||
|         this.$replaceButton.on("click", () => this.replace()); | ||||
| 
 | ||||
|         this.$input.keydown(async (e) => { | ||||
|         this.$input.on("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
 | ||||
|                 // whole input to find
 | ||||
| @ -172,7 +172,7 @@ export default class FindWidget extends NoteContextAwareWidget { | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         this.$widget.keydown(async (e) => { | ||||
|         this.$widget.on("keydown", async (e) => { | ||||
|             if (e.key === "Escape") { | ||||
|                 await this.closeSearch(); | ||||
|             } | ||||
| @ -197,9 +197,14 @@ export default class FindWidget extends NoteContextAwareWidget { | ||||
|         const isReadOnly = await this.noteContext?.isReadOnly(); | ||||
| 
 | ||||
|         let selectedText = ""; | ||||
|         if (this.note?.type === "code" && !isReadOnly && this.noteContext) { | ||||
|             const codeEditor = await this.noteContext.getCodeEditor(); | ||||
|             selectedText = codeEditor.getSelection(); | ||||
|         if (this.note?.type === "code" && this.noteContext) { | ||||
|             if (isReadOnly){ | ||||
|                 const $content = await this.noteContext.getContentElement(); | ||||
|                 selectedText = $content.find('.cm-matchhighlight').first().text(); | ||||
|             } else { | ||||
|                 const codeEditor = await this.noteContext.getCodeEditor(); | ||||
|                 selectedText = codeEditor.getSelection(); | ||||
|             } | ||||
|         } else { | ||||
|             selectedText = window.getSelection()?.toString() || ""; | ||||
|         } | ||||
| @ -235,6 +240,12 @@ export default class FindWidget extends NoteContextAwareWidget { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async readOnlyTemporarilyDisabledEvent({ noteContext }: EventData<"readOnlyTemporarilyDisabled">) { | ||||
|         if (this.isNoteContext(noteContext.ntxId)) { | ||||
|             await this.closeSearch(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async getHandler() { | ||||
|         if (this.note?.type === "render") { | ||||
|             return this.htmlHandler; | ||||
|  | ||||
| @ -2,7 +2,6 @@ | ||||
| // uses for highlighting matches, use the same one on CodeMirror
 | ||||
| // for consistency
 | ||||
| import utils from "../services/utils.js"; | ||||
| import appContext from "../components/app_context.js"; | ||||
| import type FindWidget from "./find.js"; | ||||
| import type { FindResult } from "./find.js"; | ||||
| 
 | ||||
| @ -39,12 +38,16 @@ export default class FindInHtml { | ||||
|                         caseSensitive: matchCase, | ||||
|                         done: async () => { | ||||
|                             this.$results = $content.find(`.${FIND_RESULT_CSS_CLASSNAME}`); | ||||
|                             this.currentIndex = 0; | ||||
|                             const scrollingContainer = $content[0].closest('.scrolling-container'); | ||||
|                             const containerTop = scrollingContainer?.getBoundingClientRect().top ?? 0; | ||||
|                             const closestIndex = this.$results.toArray().findIndex(el => el.getBoundingClientRect().top >= containerTop); | ||||
|                             this.currentIndex = closestIndex >= 0 ? closestIndex : 0; | ||||
|                              | ||||
|                             await this.jumpTo(); | ||||
| 
 | ||||
|                             res({ | ||||
|                                 totalFound: this.$results.length, | ||||
|                                 currentFound: Math.min(1, this.$results.length) | ||||
|                                 currentFound: this.$results.length > 0 ? this.currentIndex + 1 : 0 | ||||
|                             }); | ||||
|                         } | ||||
|                     }); | ||||
| @ -71,27 +74,17 @@ export default class FindInHtml { | ||||
| 
 | ||||
|     async findBoxClosed(totalFound: number, currentFound: number) { | ||||
|         const $content = await this.parent?.noteContext?.getContentElement(); | ||||
|         if ($content) { | ||||
|         if (typeof $content?.unmark === 'function') { | ||||
|             $content.unmark(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async jumpTo() { | ||||
|         if (this.$results?.length) { | ||||
|             const offsetTop = 100; | ||||
|             const $current = this.$results.eq(this.currentIndex); | ||||
|             this.$results.removeClass(FIND_RESULT_SELECTED_CSS_CLASSNAME); | ||||
| 
 | ||||
|             if ($current.length) { | ||||
|                 $current.addClass(FIND_RESULT_SELECTED_CSS_CLASSNAME); | ||||
|                 const position = $current.position().top - offsetTop; | ||||
| 
 | ||||
|                 const $content = await this.parent.noteContext?.getContentElement(); | ||||
|                 if ($content) { | ||||
|                     const $contentWidget = appContext.getComponentByEl($content[0]); | ||||
|                     $contentWidget.triggerCommand("scrollContainerTo", { position }); | ||||
|                 } | ||||
|             } | ||||
|             $current[0].scrollIntoView(); | ||||
|             $current.addClass(FIND_RESULT_SELECTED_CSS_CLASSNAME); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -55,15 +55,26 @@ export default class FindInText { | ||||
|             const options = { matchCase: matchCase, wholeWords: wholeWord }; | ||||
|             findResult = textEditor.execute("find", searchTerm, options); | ||||
|             totalFound = findResult.results.length; | ||||
|             // Find the result beyond the cursor
 | ||||
|             const cursorPos = model.document.selection.getLastPosition(); | ||||
|             for (let i = 0; i < findResult.results.length; ++i) { | ||||
|                 const marker = findResult.results.get(i)?.marker; | ||||
|                 const fromPos = marker?.getStart(); | ||||
|                 if (cursorPos && fromPos && fromPos.compareWith(cursorPos) !== "before") { | ||||
|                     currentFound = i; | ||||
|                     break; | ||||
|             const selection = model.document.selection; | ||||
|             // If text is selected, highlight the corresponding result;
 | ||||
|             // otherwise, highlight the first visible result in the scrolling container.
 | ||||
|             if (!selection.isCollapsed) { | ||||
|                 const cursorPos = selection.getFirstPosition(); | ||||
|                 for (let i = 0; i < findResult.results.length; ++i) { | ||||
|                     const marker = findResult.results.get(i)?.marker; | ||||
|                     const fromPos = marker?.getStart(); | ||||
|                     if (cursorPos && fromPos?.compareWith(cursorPos) !== "before") { | ||||
|                         currentFound = i; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 const editorEl = textEditor?.sourceElement; | ||||
|                 const findResultElement = editorEl?.querySelectorAll(".ck-find-result"); | ||||
|                 const scrollingContainer = editorEl?.closest('.scrolling-container'); | ||||
|                 const containerTop = scrollingContainer?.getBoundingClientRect().top ?? 0; | ||||
|                 const closestIndex = Array.from(findResultElement ?? []).findIndex((el) => el.getBoundingClientRect().top >= containerTop); | ||||
|                 currentFound = closestIndex >= 0 ? closestIndex : 0; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Elian Doran
						Elian Doran