From a823c756c0904b195bcdb02e81799c58832bf564 Mon Sep 17 00:00:00 2001 From: "circleci-app[bot]" <127350680+circleci-app[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 21:12:35 +0000 Subject: [PATCH] fix: multiple bugs and cleanup across extension codebase - Fix "Open Twitter" action dispatching OPEN_FACEBOOK instead of OPEN_TWITTER - Fix cleanTabUrl corrupting URLs with query strings but no hash (slice(-1) bug) - Fix isBrowserURL returning undefined on non-Chrome/Firefox browsers - Fix indexOfSelected useMemo missing resultList in dependency array - Fix onInputChange debounce recreated every render (wrap in useRef) - Fix bookmark.url non-null assertion on nodes without a url field - Remove console.log debugging artifacts from background service worker - Refactor scoreData to eliminate duplicated single-key/multi-key branches - Remove redundant `=== 0` check subsumed by threshold comparison AI-Generated: true --- src/background/background.ts | 7 +-- src/background/search/actions.ts | 2 +- src/background/search/index.ts | 40 +++++----------- src/background/utils.ts | 13 +++--- src/common/common.ts | 3 +- src/content/ui/components/SearchModal.tsx | 57 +++++++++++------------ 6 files changed, 49 insertions(+), 73 deletions(-) diff --git a/src/background/background.ts b/src/background/background.ts index 6f6b418..f470256 100644 --- a/src/background/background.ts +++ b/src/background/background.ts @@ -35,18 +35,14 @@ browser.runtime.onInstalled.addListener(({ reason }) => { } }); -browser.commands.onCommand.addListener((command, tab) => { - console.log(tab); - // should I still check the command? +browser.commands.onCommand.addListener((_command, _tab) => { getCurrentTab().then((currentTab) => { - console.log(currentTab) if ( currentTab?.id && currentTab.url && // chrome does not like content scripts acting on thier urls !isBrowserURL(currentTab.url) ) { - console.log(tab?.id === currentTab.id); const messagePayload: MessagePlayload = { message: Message.TOGGLE_TAB_BUTLER_MODAL, }; @@ -145,7 +141,6 @@ browser.runtime.onMessage.addListener( break; case Message.WEB_SEARCH: { - console.log("here", messagePayload); const { query } = messagePayload as ActionPayload; if (query) { browser.search.query({ text: query, disposition: "NEW_TAB" }); diff --git a/src/background/search/actions.ts b/src/background/search/actions.ts index 6bf8102..fe88d4e 100644 --- a/src/background/search/actions.ts +++ b/src/background/search/actions.ts @@ -65,7 +65,7 @@ export const actions: ActionData[] = [ { name: "Open Twitter", id: nanoid(), - message: Message.OPEN_FACEBOOK, + message: Message.OPEN_TWITTER, type: DataType.ACTION, }, ]; diff --git a/src/background/search/index.ts b/src/background/search/index.ts index c46355f..fb7b675 100644 --- a/src/background/search/index.ts +++ b/src/background/search/index.ts @@ -122,40 +122,22 @@ function scoreData( keys: keyof T | Array, boostPercentage?: number ) { + const normalizedKeys = Array.isArray(keys) ? keys : [keys]; const dataLength = data.length; let results: ScoredDataType[] = []; - if (!Array.isArray(keys)) { - for (let i = 0; i < dataLength; i++) { - const item = data[i]; - let score = matchScore(query, item[keys] as string); - if (score < DEFAULT_SCORE_THRESHOLD) continue; - if (boostPercentage !== undefined) { - // think about this - score += score * boostPercentage; // get the percentage and add it to the score - } - results.push({ score, data: item }); + for (let i = 0; i < dataLength; i++) { + const item = data[i]; + let maxScore = 0; + for (const key of normalizedKeys) { + const score = matchScore(query, item[key] as string); + if (score > maxScore) maxScore = score; } - } else { - for (let i = 0; i < dataLength; i++) { - const item = data[i]; - const keyLength = keys.length; - let maxScore = 0; - for (let j = 0; j < keyLength; j++) { - const key = keys[j]; - const score = matchScore(query, item[key] as string); - if (score < DEFAULT_SCORE_THRESHOLD) continue; - if (score > maxScore) { - maxScore = score; - } - } - if (maxScore === 0 || maxScore < DEFAULT_SCORE_THRESHOLD) continue; - if (boostPercentage !== undefined) { - // think about this - maxScore += maxScore * boostPercentage; // get the percentage and add it to the score - } - results.push({ score: maxScore, data: item }); + if (maxScore < DEFAULT_SCORE_THRESHOLD) continue; + if (boostPercentage !== undefined) { + maxScore += maxScore * boostPercentage; } + results.push({ score: maxScore, data: item }); } if (results.length === 0) { diff --git a/src/background/utils.ts b/src/background/utils.ts index e26b31e..6b06757 100644 --- a/src/background/utils.ts +++ b/src/background/utils.ts @@ -25,9 +25,10 @@ const cleanTabUrl = (url: string) => { // https://bobbyhadz.com/blog/javascript-remove-querystring-from-url // this method removes all the query params but leaves the hash // the hash is kept as in some cases, it can help users "match" with what they are looking for (eg: a section title in a website they are on) - if (url.includes("?")) { - return url.slice(0, url.indexOf("?")) + url.slice(url.indexOf("#")); - } else return url; + const queryIndex = url.indexOf("?"); + if (queryIndex === -1) return url; + const hashIndex = url.indexOf("#"); + return url.slice(0, queryIndex) + (hashIndex !== -1 ? url.slice(hashIndex) : ""); }; export async function fetchAllTabs() { @@ -95,14 +96,14 @@ function normalizeBookmarks(bookmarks: browser.Bookmarks.BookmarkTreeNode[]) { const bookmark = bookmarks[i]; if (bookmark.children) { results.push(...normalizeBookmarks(bookmark.children)); - } else { + } else if (bookmark.url) { results.push({ type: DataType.BOOKMARK, id: nanoid(), title: bookmark.title, - url: bookmark.url!, // should be present if it since it is not a folder + url: bookmark.url, }); - } + } } return results; } diff --git a/src/common/common.ts b/src/common/common.ts index 7925d33..0a72b29 100644 --- a/src/common/common.ts +++ b/src/common/common.ts @@ -1,10 +1,11 @@ export const isFirefox = () => navigator.userAgent.includes("Firefox"); export const isChrome = () => navigator.userAgent.includes("Chrome"); -export function isBrowserURL(url: string) { +export function isBrowserURL(url: string): boolean { if (url === "about:blank") return true; if (isChrome()) return isChromeURL(url); if (isFirefox()) return isFirefoxURL(url); + return false; } export function isChromeURL(url: string) { diff --git a/src/content/ui/components/SearchModal.tsx b/src/content/ui/components/SearchModal.tsx index c776c88..9a41b4b 100644 --- a/src/content/ui/components/SearchModal.tsx +++ b/src/content/ui/components/SearchModal.tsx @@ -52,7 +52,7 @@ export const SearchModal = (props: Props) => { ); return foundId === -1 ? null : foundId; } else return null; - }, [selectedId]); + }, [selectedId, resultList]); const inputRef = useRef>(null); @@ -187,36 +187,33 @@ export const SearchModal = (props: Props) => { } }; - const onInputChange = debounce((query: string) => { - if (query) { - search(query) - .then((result) => { - // if the the input is currently empty, dont try and and set the result/render an error - if (!inputRef.current?.value) return; - // console.log(result); - if (result.hasError) { - setError(true); - } else if (result.data !== null) { - // console.log(result.data); - const { sections, sortedResult } = result.data; - setResultSections(sections); - setResultList(sortedResult); - // select the first item - if (sortedResult.length === 0) { - setSelectedId(null); - } else { - setSelectedId(sortedResult[0].data.id); + const onInputChange = useRef( + debounce((query: string) => { + if (query) { + search(query) + .then((result) => { + // if the the input is currently empty, dont try and and set the result/render an error + if (!inputRef.current?.value) return; + if (result.hasError) { + setError(true); + } else if (result.data !== null) { + const { sections, sortedResult } = result.data; + setResultSections(sections); + setResultList(sortedResult); + // select the first item + if (sortedResult.length === 0) { + setSelectedId(null); + } else { + setSelectedId(sortedResult[0].data.id); + } } - // result.data && setResultSections(result.data); - } - }) - .catch(() => { - // console.log("here is the err", err); - // console.log("here in the catch"); - setError(true); - }); - } - }, 300); + }) + .catch(() => { + setError(true); + }); + } + }, 300), + ).current; const closeOnClick = (func: (data: T) => void) => { return (data: T) => {