diff --git a/apps/client/src/widgets/collections/legacy/ListView.tsx b/apps/client/src/widgets/collections/legacy/ListView.tsx
index 62f6505fd..c25f4ac55 100644
--- a/apps/client/src/widgets/collections/legacy/ListView.tsx
+++ b/apps/client/src/widgets/collections/legacy/ListView.tsx
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import FNote from "../../../entities/fnote";
import Icon from "../../react/Icon";
import { ViewModeProps } from "../interface";
-import { useNoteLabelBoolean, useNoteProperty } from "../../react/hooks";
+import { useNoteLabelBoolean, useImperativeSearchHighlighlighting } from "../../react/hooks";
import NoteLink from "../../react/NoteLink";
import "./ListOrGridView.css";
import content_renderer from "../../../services/content_renderer";
@@ -75,8 +75,8 @@ function ListNoteCard({ note, parentNote, expand, highlightedTokens }: { note: F
{isExpanded && <>
-
-
+
+
>}
@@ -104,7 +104,7 @@ function GridNoteCard({ note, parentNote, highlightedTokens }: { note: FNote, pa
{noteTitle}
-
+
)
}
@@ -120,26 +120,29 @@ function NoteAttributes({ note }: { note: FNote }) {
return
}
-function NoteContent({ note, trim }: { note: FNote, trim?: boolean }) {
+function NoteContent({ note, trim, highlightedTokens }: { note: FNote, trim?: boolean, highlightedTokens }) {
const contentRef = useRef(null);
+ const highlightSearch = useImperativeSearchHighlighlighting(highlightedTokens);
useEffect(() => {
content_renderer.getRenderedContent(note, { trim })
.then(({ $renderedContent, type }) => {
- contentRef.current?.replaceChildren(...$renderedContent);
- contentRef.current?.classList.add(`type-${type}`);
+ if (!contentRef.current) return;
+ contentRef.current.replaceChildren(...$renderedContent);
+ contentRef.current.classList.add(`type-${type}`);
+ highlightSearch(contentRef.current);
})
.catch(e => {
console.warn(`Caught error while rendering note '${note.noteId}' of type '${note.type}'`);
console.error(e);
contentRef.current?.replaceChildren(t("collections.rendering_error"));
})
- }, [ note ]);
+ }, [ note, highlightedTokens ]);
return ;
}
-function NoteChildren({ note, parentNote }: { note: FNote, parentNote: FNote }) {
+function NoteChildren({ note, parentNote, highlightedTokens }: { note: FNote, parentNote: FNote, highlightedTokens: string[] | null | undefined }) {
const imageLinks = note.getRelations("imageLink");
const [ childNotes, setChildNotes ] = useState();
@@ -150,7 +153,7 @@ function NoteChildren({ note, parentNote }: { note: FNote, parentNote: FNote })
});
}, [ note ]);
- return childNotes?.map(childNote => )
+ return childNotes?.map(childNote => )
}
/**
diff --git a/apps/client/src/widgets/react/NoteLink.tsx b/apps/client/src/widgets/react/NoteLink.tsx
index 4d7925bf7..2a9ec199d 100644
--- a/apps/client/src/widgets/react/NoteLink.tsx
+++ b/apps/client/src/widgets/react/NoteLink.tsx
@@ -1,7 +1,6 @@
import { useEffect, useRef, useState } from "preact/hooks";
import link from "../../services/link";
-import RawHtml from "./RawHtml";
-import { useSearchHighlighlighting } from "./hooks";
+import { useImperativeSearchHighlighlighting } from "./hooks";
interface NoteLinkOpts {
className?: string;
@@ -16,15 +15,21 @@ interface NoteLinkOpts {
export default function NoteLink({ className, notePath, showNotePath, showNoteIcon, style, noPreview, noTnLink, highlightedTokens }: NoteLinkOpts) {
const stringifiedNotePath = Array.isArray(notePath) ? notePath.join("/") : notePath;
+ const ref = useRef(null);
const [ jqueryEl, setJqueryEl ] = useState>();
- const containerRef = useRef(null);
- useSearchHighlighlighting(containerRef, highlightedTokens);
+ const highlightSearch = useImperativeSearchHighlighlighting(highlightedTokens);
useEffect(() => {
link.createLink(stringifiedNotePath, { showNotePath, showNoteIcon })
.then(setJqueryEl);
}, [ stringifiedNotePath, showNotePath ]);
+ useEffect(() => {
+ if (!ref.current || !jqueryEl) return;
+ ref.current.replaceChildren(jqueryEl[0]);
+ highlightSearch(ref.current);
+ }, [ jqueryEl ]);
+
if (style) {
jqueryEl?.css(style);
}
@@ -42,6 +47,6 @@ export default function NoteLink({ className, notePath, showNotePath, showNoteIc
$linkEl?.addClass(className);
}
- return
+ return
}
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx
index fa6c901bc..b4148197d 100644
--- a/apps/client/src/widgets/react/hooks.tsx
+++ b/apps/client/src/widgets/react/hooks.tsx
@@ -550,7 +550,7 @@ export function useSyncedRef(externalRef?: RefObject, initialValue: T | nu
return ref;
}
-export function useSearchHighlighlighting(ref: RefObject, highlightedTokens: string[] | null | undefined) {
+export function useImperativeSearchHighlighlighting(highlightedTokens: string[] | null | undefined) {
const mark = useRef();
const highlightRegex = useMemo(() => {
if (!highlightedTokens?.length) return null;
@@ -558,18 +558,17 @@ export function useSearchHighlighlighting(ref: RefObject, highlight
return new RegExp(regex, "gi")
}, [ highlightedTokens ]);
- useEffect(() => {
- if (!ref.current || !highlightRegex) return;
+ return (el: HTMLElement) => {
+ if (!el || !highlightRegex) return;
if (!mark.current) {
- mark.current = new Mark(ref.current);
+ mark.current = new Mark(el);
}
+ mark.current.unmark();
mark.current.markRegExp(highlightRegex, {
element: "span",
className: "ck-find-result"
});
-
- return () => mark.current?.unmark();
- });
+ };
}