diff --git a/extensions/react-widget/src/components/SearchBar.tsx b/extensions/react-widget/src/components/SearchBar.tsx
index e88bdafd..16072643 100644
--- a/extensions/react-widget/src/components/SearchBar.tsx
+++ b/extensions/react-widget/src/components/SearchBar.tsx
@@ -6,7 +6,7 @@ import { getSearchResults } from '../requests/searchAPI'
import { Result } from '@/types';
import MarkdownIt from 'markdown-it';
import DOMPurify from 'dompurify';
-import { getOS } from '../utils/helper'
+import { getOS, preprocessSearchResultsToHTML } from '../utils/helper'
const themes = {
dark: {
bg: '#000',
@@ -291,6 +291,8 @@ export const SearchBar = ({
}, 500);
return () => {
+ console.log(results);
+
abortController.abort();
clearTimeout(debounceTimeout.current ?? undefined);
};
@@ -352,7 +354,7 @@ export const SearchBar = ({
{res.title}
diff --git a/extensions/react-widget/src/utils/helper.ts b/extensions/react-widget/src/utils/helper.ts
index 39c720e2..eb2f836f 100644
--- a/extensions/react-widget/src/utils/helper.ts
+++ b/extensions/react-widget/src/utils/helper.ts
@@ -1,27 +1,76 @@
+import MarkdownIt from "markdown-it";
+import DOMPurify from "dompurify";
export const getOS = () => {
- const platform = window.navigator.platform;
- const userAgent = window.navigator.userAgent || window.navigator.vendor;
-
- if (/Mac/i.test(platform)) {
- return 'mac';
- }
-
- if (/Win/i.test(platform)) {
- return 'win';
- }
-
- if (/Linux/i.test(platform) && !/Android/i.test(userAgent)) {
- return 'linux';
- }
-
- if (/Android/i.test(userAgent)) {
- return 'android';
- }
-
- if (/iPhone|iPad|iPod/i.test(userAgent)) {
- return 'ios';
- }
-
- return 'other';
- };
-
\ No newline at end of file
+ const platform = window.navigator.platform;
+ const userAgent = window.navigator.userAgent || window.navigator.vendor;
+
+ if (/Mac/i.test(platform)) {
+ return 'mac';
+ }
+
+ if (/Win/i.test(platform)) {
+ return 'win';
+ }
+
+ if (/Linux/i.test(platform) && !/Android/i.test(userAgent)) {
+ return 'linux';
+ }
+
+ if (/Android/i.test(userAgent)) {
+ return 'android';
+ }
+
+ if (/iPhone|iPad|iPod/i.test(userAgent)) {
+ return 'ios';
+ }
+
+ return 'other';
+};
+
+export const preprocessSearchResultsToHTML = (text: string, keyword: string) => {
+ const md = new MarkdownIt();
+ const htmlString = md.render(text);
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(htmlString, "text/html");
+
+ const filteredResults = document.createElement("div")
+ recursiveFilter(doc.body, keyword, filteredResults)
+ console.log(filteredResults)
+
+ return DOMPurify.sanitize(filteredResults)
+
+}
+
+const recursiveFilter = (element: Node, keyword: string, parent: Node | null) => {
+ const content = element.textContent?.toLowerCase() ?? null;
+ const childNodes = element.childNodes
+ childNodes.forEach((child) => {
+ if (recursiveFilter(child, keyword, element))
+ parent?.appendChild(highlightFilteredContent(child, keyword))
+ })
+ if (content && content.includes(keyword.toLowerCase())) {
+ return true
+ }
+ return false
+}
+
+const highlightFilteredContent = (element: Node, keyword: string) => {
+ if (!element.textContent || !keyword.trim()) return element;
+
+ const regex = new RegExp(`(${keyword})`, 'gi');
+ const splitted = element.textContent.split(regex);
+ console.log(splitted);
+
+ // Create a new HTML string with the keyword wrapped in a
+ const highlightedHTML = splitted
+ .map((part) =>
+ regex.test(part)
+ ? `${part}`
+ : part
+ )
+ .join("");
+ if (element instanceof HTMLElement) {
+ element.innerHTML = highlightedHTML;
+ }
+ return element
+};
\ No newline at end of file