diff --git a/.gitignore b/.gitignore index dc0131f..88a0e70 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,10 @@ sidebar.js lib/* /yarn-error.log /rentgen.zip + +# Generated PNG icons (build artifacts) +/assets/icons/*.png +/assets/icon-addon-*.png + +# Exception: do not ignore the `browser-api` directory inside `lib` +!/lib/browser-api/ \ No newline at end of file diff --git a/lib/browser-api/chrome.ts b/lib/browser-api/chrome.ts new file mode 100644 index 0000000..5431819 --- /dev/null +++ b/lib/browser-api/chrome.ts @@ -0,0 +1,54 @@ +/** + * Chrome Browser API Implementation + * + * Mapuje Chrome chrome.* API na nasze ujednolicone BrowserAPI + */ + +import type { BrowserAPI } from './types'; + +// Chrome używa globalnego obiektu `chrome` +declare const chrome: any; + +export const chromeAPI: BrowserAPI = { + // Tabs API - chrome.tabs.* → tabs.* + tabs: { + query: chrome.tabs.query, + onUpdated: { + addListener: chrome.tabs.onUpdated.addListener, + removeListener: chrome.tabs.onUpdated.removeListener, + }, + }, + + // Badge API - Chrome używa action (nie browserAction) + badge: { + setBadgeText: chrome.action.setBadgeText, + setTitle: chrome.action.setTitle, + setBadgeBackgroundColor: chrome.action.setBadgeBackgroundColor, + }, + + // WebRequest API - chrome.webRequest.* → webRequest.* + webRequest: { + onBeforeRequest: { + addListener: chrome.webRequest.onBeforeRequest.addListener, + }, + onBeforeSendHeaders: { + addListener: chrome.webRequest.onBeforeSendHeaders.addListener, + }, + }, + + // Cookies API - chrome.cookies.* → cookies.* + cookies: { + getAll: chrome.cookies.getAll, + remove: chrome.cookies.remove, + }, + + // Extension API - chrome.extension.* → extension.* + extension: { + getBackgroundPage: chrome.extension.getBackgroundPage, + }, + + // Windows API - chrome.windows.* → windows.* + windows: { + WINDOW_ID_CURRENT: chrome.windows.WINDOW_ID_CURRENT, + }, +}; \ No newline at end of file diff --git a/lib/browser-api/firefox.ts b/lib/browser-api/firefox.ts new file mode 100644 index 0000000..911f0a7 --- /dev/null +++ b/lib/browser-api/firefox.ts @@ -0,0 +1,54 @@ +/** + * Firefox Browser API Implementation + * + * Mapuje Firefox browser.* API na nasze ujednolicone BrowserAPI + */ + +import type { BrowserAPI } from './types'; + +// Firefox używa globalnego obiektu `browser` +declare const browser: any; + +export const firefoxAPI: BrowserAPI = { + // Tabs API - direct mapping + tabs: { + query: browser.tabs.query, + onUpdated: { + addListener: browser.tabs.onUpdated.addListener, + removeListener: browser.tabs.onUpdated.removeListener, + }, + }, + + // Badge API - Firefox używa browserAction + badge: { + setBadgeText: browser.browserAction.setBadgeText, + setTitle: browser.browserAction.setTitle, + setBadgeBackgroundColor: browser.browserAction.setBadgeBackgroundColor, + }, + + // WebRequest API - direct mapping + webRequest: { + onBeforeRequest: { + addListener: browser.webRequest.onBeforeRequest.addListener, + }, + onBeforeSendHeaders: { + addListener: browser.webRequest.onBeforeSendHeaders.addListener, + }, + }, + + // Cookies API - direct mapping + cookies: { + getAll: browser.cookies.getAll, + remove: browser.cookies.remove, + }, + + // Extension API - direct mapping + extension: { + getBackgroundPage: browser.extension.getBackgroundPage, + }, + + // Windows API - direct mapping + windows: { + WINDOW_ID_CURRENT: browser.windows.WINDOW_ID_CURRENT, + }, +}; \ No newline at end of file diff --git a/lib/browser-api/index.ts b/lib/browser-api/index.ts new file mode 100644 index 0000000..119d6c1 --- /dev/null +++ b/lib/browser-api/index.ts @@ -0,0 +1,27 @@ +/** + * Browser API Abstraction - Main Export + * + * Eksportuje właściwą implementację na podstawie TARGET build variable + */ + +import type { BrowserAPI } from './types'; + +// Build-time selection of browser API implementation +let browserApi: BrowserAPI; + +// TARGET jest ustawiane przez esbuild.config.js na podstawie npm script +if (process.env.TARGET === 'chrome') { + // Chrome build - używamy chrome adapter + const { chromeAPI } = require('./chrome'); + browserApi = chromeAPI; +} else { + // Firefox build (default) - używamy firefox adapter + const { firefoxAPI } = require('./firefox'); + browserApi = firefoxAPI; +} + +// Eksportuj jako default export +export default browserApi; + +// Re-export typów dla wygody +export * from './types'; \ No newline at end of file diff --git a/lib/browser-api/types.ts b/lib/browser-api/types.ts new file mode 100644 index 0000000..8e7cf41 --- /dev/null +++ b/lib/browser-api/types.ts @@ -0,0 +1,124 @@ +/** + * Browser API Abstraction - Typy na podstawie faktycznego użycia w kodzie + * + * Przeanalizowane pliki: + * - util.ts: tabs.query, Tab.id + * - tab-dropdown.tsx: tabs.query, Tab.id, Tab.title + * - toolbar.tsx: tabs.query, tabs.onUpdated, Tab.url, windows.WINDOW_ID_CURRENT + * - memory.ts: browserAction.*, webRequest.*, cookies.*, extension.* + */ + +// === Tab API (util.ts, tab-dropdown.tsx, toolbar.tsx) === +export interface Tab { + id?: number; // util.ts: tab.id, tab-dropdown.tsx: tab.id + title?: string; // tab-dropdown.tsx: tab.title + url?: string; // toolbar.tsx: tab.url +} + +export interface TabQuery { + currentWindow?: boolean; // util.ts, tab-dropdown.tsx + active?: boolean; // toolbar.tsx + windowId?: number; // toolbar.tsx +} + +// === Badge/BrowserAction API (memory.ts) === +export interface BadgeTextDetails { + text: string; // memory.ts: setBadgeText + tabId?: number; // memory.ts: setBadgeText (optional) +} + +export interface BadgeTitleDetails { + title: string; // memory.ts: setTitle + tabId?: number; // memory.ts: setTitle (optional) +} + +export interface BadgeColorDetails { + color: string; // memory.ts: setBadgeBackgroundColor +} + +// === WebRequest API (memory.ts) === +export interface RequestDetails { + requestId: string; // memory.ts: request.requestId + requestHeaders?: RequestHeader[]; // memory.ts: request.requestHeaders + // Note: ExtendedRequest konstruktor używa więcej pól, + // ale tu skupiamy się na tym co bezpośrednio używa browser API +} + +export interface RequestHeader { + name: string; + value?: string; +} + +export interface RequestFilter { + urls: string[]; // memory.ts: { urls: [''] } +} + +export type RequestListener = (details: RequestDetails) => void; + +// === Cookies API (memory.ts) === +export interface Cookie { + name: string; // memory.ts: cookie.name + domain: string; // memory.ts: cookie.domain +} + +export interface CookieQuery { + domain?: string; // memory.ts: { domain: shorthost } +} + +export interface CookieRemove { + name: string; // memory.ts: { name: cookie.name, url: ... } + url: string; // memory.ts: { url: `https://${cookie.domain}` } +} + +// === Main Browser API Interface === +export interface BrowserAPI { + // Tabs API + tabs: { + query(queryInfo: TabQuery): Promise; + onUpdated: { + addListener(listener: (tabId: number, changeInfo: any, tab: Tab) => void): void; + removeListener(listener: (tabId: number, changeInfo: any, tab: Tab) => void): void; + }; + }; + + // Badge API (Firefox: browserAction, Chrome: action) + badge: { + setBadgeText(details: BadgeTextDetails): void; + setTitle(details: BadgeTitleDetails): void; + setBadgeBackgroundColor(details: BadgeColorDetails): void; + }; + + // WebRequest API + webRequest: { + onBeforeRequest: { + addListener( + listener: RequestListener, + filter: RequestFilter, + extraInfoSpec?: string[] + ): void; + }; + onBeforeSendHeaders: { + addListener( + listener: RequestListener, + filter: RequestFilter, + extraInfoSpec?: string[] + ): void; + }; + }; + + // Cookies API + cookies: { + getAll(details: CookieQuery): Promise; + remove(details: CookieRemove): Promise; + }; + + // Extension API + extension: { + getBackgroundPage(): Window | null; + }; + + // Windows API + windows: { + WINDOW_ID_CURRENT: number; + }; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e90d0c8..b4185d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "tai-password-strength": "^1.1.3" }, "devDependencies": { + "@types/chrome": "^0.1.3", "@types/events": "^3.0.0", "@types/react-dom": "^17.0.9", "addons-linter": "^4.7.0", @@ -319,6 +320,16 @@ "node": ">=6" } }, + "node_modules/@types/chrome": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.3.tgz", + "integrity": "sha512-KVOIHEKjDZXMg8c18Ir3kbLc+bb8JxZjNJv27Wen3F0I/eeTyrYm7tWOjGhoBjI9fFQfjsTSyFcENBo9Wbl5kw==", + "dev": true, + "dependencies": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, "node_modules/@types/decompress": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.4.tgz", @@ -347,6 +358,21 @@ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, + "node_modules/@types/filesystem": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz", + "integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==", + "dev": true, + "dependencies": { + "@types/filewriter": "*" + } + }, + "node_modules/@types/filewriter": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz", + "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==", + "dev": true + }, "node_modules/@types/got": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/@types/got/-/got-8.3.6.tgz", @@ -357,6 +383,12 @@ "@types/node": "*" } }, + "node_modules/@types/har-format": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz", + "integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -7390,6 +7422,16 @@ "defer-to-connect": "^1.0.1" } }, + "@types/chrome": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.1.3.tgz", + "integrity": "sha512-KVOIHEKjDZXMg8c18Ir3kbLc+bb8JxZjNJv27Wen3F0I/eeTyrYm7tWOjGhoBjI9fFQfjsTSyFcENBo9Wbl5kw==", + "dev": true, + "requires": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, "@types/decompress": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.4.tgz", @@ -7418,6 +7460,21 @@ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, + "@types/filesystem": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz", + "integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==", + "dev": true, + "requires": { + "@types/filewriter": "*" + } + }, + "@types/filewriter": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz", + "integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==", + "dev": true + }, "@types/got": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/@types/got/-/got-8.3.6.tgz", @@ -7428,6 +7485,12 @@ "@types/node": "*" } }, + "@types/har-format": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz", + "integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==", + "dev": true + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", diff --git a/package.json b/package.json index 3bcefc4..f1362be 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,23 @@ { "name": "rentgen", "version": "0.1.10", - "description": "Rentgen is an add-on prepared for Firefox-based browsers. This extension will automatically visualize all the data that a given website sends to third parties.", + "description": "Rentgen is an add-on prepared for both Firefox-based and Chromium-based browsers. This extension will automatically visualize all the data that a given website sends to third parties.", "main": "esbuild.config.js", "type": "module", "scripts": { "build": "node esbuild.config.js", + "build:firefox": "TARGET=firefox node esbuild.config.js", + "build:chrome": "TARGET=chrome node esbuild.config.js", "watch": "node esbuild.config.js --watch", + "watch:firefox": "TARGET=firefox node esbuild.config.js --watch", + "watch:chrome": "TARGET=chrome node esbuild.config.js --watch", "ext-test": "web-ext run", "build-addon": "npm i && npm run build && npm run create-package", + "build-addon:firefox": "npm i && npm run build:firefox && npm run create-package:firefox", + "build-addon:chrome": "npm i && npm run build:chrome && npm run create-package:chrome", "create-package": "web-ext build --ignore-files '!**/node_modules' '!**/node_modules/**/react-dom' '!**/node_modules/**/react-dom/umd' '!**/node_modules/**/*/react-dom.production.min.js' '!**/node_modules/**/react' '!**/node_modules/**/react/umd' '!**/node_modules/**/*/react.production.min.js' '!**/node_modules/**/survey-react' '!**/node_modules/**/survey-react/*.min.js' '!**/node_modules/**/survey-react/*.min.css' --overwrite-dest", + "create-package:firefox": "cd dist-firefox && web-ext build --overwrite-dest --artifacts-dir ../web-ext-artifacts", + "create-package:chrome": "cd dist-chrome && 7z a -tzip ../web-ext-artifacts/rentgen-chrome-0.1.10.zip * && cd ..", "typecheck": "tsc --noEmit", "lint": "web-ext lint" }, @@ -43,6 +51,7 @@ "tracking" ], "devDependencies": { + "@types/chrome": "^0.1.3", "@types/events": "^3.0.0", "@types/react-dom": "^17.0.9", "addons-linter": "^4.7.0",