diff options
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/generate-web-page.ts | 2 | ||||
| -rw-r--r-- | src/shared/intercept-jquery-ajax.ts | 87 | ||||
| -rw-r--r-- | src/shared/modify-dom.ts | 22 | ||||
| -rw-r--r-- | src/shared/observe-dom.ts | 7 | ||||
| -rw-r--r-- | src/shared/ocr-request.ts | 13 | ||||
| -rw-r--r-- | src/shared/script-injector.ts | 10 | ||||
| -rw-r--r-- | src/shared/styling.ts | 6 |
7 files changed, 92 insertions, 55 deletions
diff --git a/src/shared/generate-web-page.ts b/src/shared/generate-web-page.ts index c3cc3a4..a93e2e2 100644 --- a/src/shared/generate-web-page.ts +++ b/src/shared/generate-web-page.ts @@ -5,7 +5,7 @@ * @param content - The full HTML string to write. * @param title - The document title (default: `"Banglar Bhumi"`). */ -export function generateWebPage(content: string, title: string = "Banglar Bhumi") { +export function generateWebPage(content: string, title = "Banglar Bhumi"): void { const tab = window.open("about:blank", "_blank"); if (!tab) { return; diff --git a/src/shared/intercept-jquery-ajax.ts b/src/shared/intercept-jquery-ajax.ts index 7e1f54e..b627d0e 100644 --- a/src/shared/intercept-jquery-ajax.ts +++ b/src/shared/intercept-jquery-ajax.ts @@ -1,61 +1,86 @@ -type InterceptJqueryAjaxCallback = (args: any) => void; +export type JQueryAjaxArgs = [ + url: string, + data: string | Record<string, unknown>, + callback: (data: unknown, textStatus: string, jqXHR: JQuery.jqXHR) => void, + dataType?: string +]; -interface InterceptJqueryEntry { - url: string; - callback: InterceptJqueryAjaxCallback; +type JQueryAjaxInterceptor = (args: JQueryAjaxArgs) => void; + +type InterceptorRegistration = { + urlSuffix: string; + interceptor: JQueryAjaxInterceptor }; -const postIntercepts: InterceptJqueryEntry[] = []; -const getIntercepts: InterceptJqueryEntry[] = []; +const postInterceptors: InterceptorRegistration[] = []; +const getInterceptors: InterceptorRegistration[] = []; + +// Define a strict signature to replace the unsafe `Function` type +type OriginalJQueryAjaxMethod = (...args: unknown[]) => JQuery.jqXHR; /** * On DOMContentLoaded, proxies jQuery's `$.post` and `$.get` so that * registered interceptors are called before the real request. */ -document.addEventListener("DOMContentLoaded", () => { - const proxiedPost = $.post; - const proxiedGet = $.get; +document.addEventListener("DOMContentLoaded", function() { + // 1. Keep the original methods bound to the jQuery ($) object + const originalPost = $.post.bind($); + const originalGet = $.get.bind($); /** Proxied `$.post` that invokes registered interceptors before the real call. */ - $.post = function() { - for (const { url, callback } of postIntercepts) { - if (arguments[0].endsWith(url)) { - callback(arguments); + $.post = function(this: typeof $, ...args: unknown[]): JQuery.jqXHR { + for (const { urlSuffix, interceptor } of postInterceptors) { + // Safely inspect jQuery settings objects without using "any" + const firstArg = args[0]; + const requestUrl = typeof firstArg === "string" + ? firstArg + : (firstArg && typeof firstArg === "object" && "url" in firstArg && typeof firstArg.url === "string" ? firstArg.url : null); + + if (typeof requestUrl === "string" && requestUrl.endsWith(urlSuffix)) { + // Cast the unknown array to the expected tuple type + interceptor(args as unknown as JQueryAjaxArgs); } } - return proxiedPost.apply(this, Array.from(arguments) as any); - }; + // Use our strict signature instead of `Function` to satisfy ESLint + return (originalPost as unknown as OriginalJQueryAjaxMethod)(...args); + } as typeof $.post; // Reassert the original type so external consumers see the normal signature + /** Proxied `$.get` that invokes registered interceptors before the real call. */ - $.get = function() { - for (const { url, callback } of getIntercepts) { - if (arguments[0].endsWith(url)) { - callback(arguments); + $.get = function(this: typeof $, ...args: unknown[]): JQuery.jqXHR { + for (const { urlSuffix, interceptor } of getInterceptors) { + const firstArg = args[0]; + const requestUrl = typeof firstArg === "string" + ? firstArg + : (firstArg && typeof firstArg === "object" && "url" in firstArg && typeof firstArg.url === "string" ? firstArg.url : null); + + if (typeof requestUrl === "string" && requestUrl.endsWith(urlSuffix)) { + interceptor(args as unknown as JQueryAjaxArgs); } } - return proxiedGet.apply(this, Array.from(arguments) as any); - }; + return (originalGet as unknown as OriginalJQueryAjaxMethod)(...args); + } as typeof $.get; }); /** * Registers a callback that fires whenever a jQuery POST request matches * the given URL suffix. * - * @param url - The URL suffix to match (checked via `endsWith`). - * @param callback - Receives the original `arguments` from `$.post`. + * @param urlSuffix - The URL suffix to match (checked via `endsWith`). + * @param interceptor - Receives the original `arguments` from `$.post`. */ -export function interceptPost(url: string, callback: InterceptJqueryAjaxCallback) { - postIntercepts.push({ url, callback }); -}; +export function addPostInterceptor(urlSuffix: string, interceptor: JQueryAjaxInterceptor): void { + postInterceptors.push({ urlSuffix, interceptor }); +} /** * Registers a callback that fires whenever a jQuery GET request matches * the given URL suffix. * - * @param url - The URL suffix to match (checked via `endsWith`). - * @param callback - Receives the original `arguments` from `$.get`. + * @param urlSuffix - The URL suffix to match (checked via `endsWith`). + * @param interceptor - Receives the original `arguments` from `$.get`. */ -export function interceptGet(url: string, callback: InterceptJqueryAjaxCallback) { - getIntercepts.push({ url, callback }); -}; +export function addGetInterceptor(urlSuffix: string, interceptor: JQueryAjaxInterceptor): void { + getInterceptors.push({ urlSuffix, interceptor }); +} diff --git a/src/shared/modify-dom.ts b/src/shared/modify-dom.ts index b268ae2..41e8730 100644 --- a/src/shared/modify-dom.ts +++ b/src/shared/modify-dom.ts @@ -2,7 +2,7 @@ import { observeDOM } from "@/shared/observe-dom"; type DOMReplacements = { innerHTML?: string; - [key: string]: string | undefined | null; + [key: string]: string | undefined | null }; type DOMModificaitonRule = readonly [string, DOMReplacements]; type DOMModificationRules = (DOMModificaitonRule | null)[]; @@ -17,23 +17,25 @@ let domModificationFinishedCount = 0; */ observeDOM(() => { for (let i = 0; i < domModificationRules.length; i++) { - if (domModificationRules[i]) { - const element = document.querySelector(domModificationRules[i]![0]) as HTMLElement | null; + const rule = domModificationRules[i]; + if (rule?.[0]) { + const element = document.querySelector(rule[0]); if (element) { - const attributes = domModificationRules[i]![1]; + const attributes = rule[1]; if (attributes.innerHTML) { - element.innerHTML = attributes.innerHTML as string; + element.innerHTML = attributes.innerHTML; } delete attributes.innerHTML; - for (const attribute in attributes) { - if (attributes[attribute] === null) { - element.removeAttribute(attribute); + for (const attributeName in attributes) { + const attribute = attributes[attributeName]; + if (attribute) { + element.setAttribute(attributeName, attribute); } else { - element.setAttribute(attribute, attributes[attribute] as string); + element.removeAttribute(attributeName); } } @@ -59,6 +61,6 @@ observeDOM(() => { * * @param modificationRules - Array of `[selector, attributes]` rules. */ -export function modifyDOM(modificationRules: DOMModificationRules) { +export function modifyDOM(modificationRules: DOMModificationRules): void { domModificationRules = domModificationRules.concat(modificationRules); }; diff --git a/src/shared/observe-dom.ts b/src/shared/observe-dom.ts index 6ba1db4..ee6a51f 100644 --- a/src/shared/observe-dom.ts +++ b/src/shared/observe-dom.ts @@ -1,6 +1,6 @@ type ObserveDOMCallback = () => boolean; -let callbacks: ObserveDOMCallback[] = []; +const callbacks: ObserveDOMCallback[] = []; /** * Starts a MutationObserver on the document that invokes each @@ -11,9 +11,8 @@ let callbacks: ObserveDOMCallback[] = []; const observer = new MutationObserver(() => { for (let i = 0; i < callbacks.length; i++) { const callback = callbacks[i]; - if (callback && callback()) { + if (callback()) callbacks.splice(i, 1); - } if (callbacks.length <= 0) { observer.disconnect(); @@ -36,6 +35,6 @@ observer.observe(document, { * * @param callback - Function that returns `true` when done. */ -export function observeDOM(callback: ObserveDOMCallback) { +export function observeDOM(callback: ObserveDOMCallback): void { callbacks.push(callback); }; diff --git a/src/shared/ocr-request.ts b/src/shared/ocr-request.ts new file mode 100644 index 0000000..3109771 --- /dev/null +++ b/src/shared/ocr-request.ts @@ -0,0 +1,13 @@ +export type OCRRequest = { + type: "OFFSCREEN_OCR_REQUEST" | "OCR"; + dataURL: string +}; + +export type OCRResponse = { + success: true; + text: string; + confidence: number +} | { + success: false; + error: string +}; diff --git a/src/shared/script-injector.ts b/src/shared/script-injector.ts index 16cb17c..3422bab 100644 --- a/src/shared/script-injector.ts +++ b/src/shared/script-injector.ts @@ -1,6 +1,4 @@ -type DataType = { - [key: string]: string -}; +type DataType = Record<string, string>; /** * Injects a `<script>` element into the document head (or `<html>`) with @@ -11,11 +9,11 @@ type DataType = { * @param src - The extension-relative script path. * @param data - Optional key/value pairs to set as `data-*` attributes. */ -export function injectScriptHead(src: string, data: DataType = {}) { - const s = document.createElement("script") as HTMLScriptElement; +export function injectScriptHead(src: string, data: DataType = {}): void { + const s = document.createElement("script"); s.src = chrome.runtime.getURL(src); for (const i in data) { s.setAttribute(`data-${i}`, data[i]); } - (document.head || document.documentElement).append(s); + document.head.append(s); }; diff --git a/src/shared/styling.ts b/src/shared/styling.ts index b19ace4..57a39f6 100644 --- a/src/shared/styling.ts +++ b/src/shared/styling.ts @@ -5,12 +5,12 @@ * @param selector - CSS selector string. * @param styles - A map of CSS property names to values. */ -export function styles(selector: string, styles: Record<string, string>) { - const elements = Array.from(document.querySelectorAll(selector)) as HTMLElement[]; +export function styles(selector: string, styles: Record<string, string>): void { + const elements = Array.from(document.querySelectorAll(selector)); for (const element of elements) { for (const styleType in styles) { - element.style[styleType as any] = styles[styleType]; + (element as HTMLElement).style.setProperty(styleType, styles[styleType]); } } }; |
