Compare commits

...

5 Commits

Author SHA1 Message Date
f1b1b6e720 Merge pull request 'chore(package.json): początek dodawania abstrakcji w build-time' (#125) from refactor/build_time_abstraction into develop
Reviewed-on: #125
2025-09-22 12:10:18 +02:00
am0
e1d9b8c874 feat(lib/browser-api): dodaj warstwę abstrakcji Browser API dla wsparcia Chrome i Firefox
Wprowadza infrastrukturę umożliwiającą budowanie rozszerzenia dla Chrome i Firefox z jednej bazy kodu. Mapuje różnice w API między przeglądarkami na ujednolicone interfejsy.

ZMIANY:
* lib/browser-api/types.ts - typy oparte na analizie rzeczywistego użycia API w kodzie
* lib/browser-api/firefox.ts - adapter mapujący browser.* na BrowserAPI
* lib/browser-api/chrome.ts - adapter mapujący chrome.* na BrowserAPI
* lib/browser-api/index.ts - build-time selection adaptera na podstawie TARGET

KLUCZOWE RÓŻNICE OBSŁUŻONE:
- Firefox: browser.browserAction.* vs Chrome: chrome.action.*
- Firefox: browser.tabs.* vs Chrome: chrome.tabs.*
- Firefox: browser.cookies.* vs Chrome: chrome.cookies.*
- Firefox: browser.webRequest.* vs Chrome: chrome.webRequest.*

TYPY OPARTE NA FAKTYCZNYM UŻYCIU:
Przeanalizowano 4 pliki używające browser API:
- memory.ts: badge, webRequest, cookies, extension API
- toolbar.tsx: tabs.query, tabs.onUpdated, windows.WINDOW_ID_CURRENT
- tab-dropdown.tsx: tabs.query
- util.ts: tabs.query

STATUS: Preparatory change - istniejący kod pozostaje niezmieniony.
Kolejne commity będą refaktorować pliki do używania nowej abstrakcji.

TARGET: Umożliwienie
> rentgen@0.1.10 build:firefox
> TARGET=firefox node esbuild.config.js

Add-on was built i
> rentgen@0.1.10 build:chrome
> TARGET=chrome node esbuild.config.js

Add-on was built
2025-09-08 10:50:09 +02:00
am0
95bb5248ef fix(ikony png): W repo będziemy trzymać tylko oryginalne ikony svg, a skalować i konwertować przy buildzie 2025-09-07 15:38:51 +02:00
d167a2138c style(icons): konwersja ikon svg na png kompatybilne z Chrome
Wygenerowanie wersji PNG (16px, 20px i 24px) wszystkich ikon SVG przy użyciu komendy Inkscape z wiersza poleceń

Główna ikona wtyczki (dla manifest.json) Chrome oczekuje konkretnych rozmiarów, stadndardowych dla Chrome (16, 32, 48, 128), ale ikony interfejsu (używane wewnątrz stron rozszerzenia) Chrome mogą mieć dowolny rozmiar, ponieważ to zwykłe obrazy w HTML. Ustawiłem je zgodnie z naszymi obecnymi rozmiarami (16, 20, 24px)

użyta komenda for svg in assets/icons/*.svg; do basename=$(basename "$svg" .svg); for size in 16 20 24; do inkscape --export-type=png --export-width=$size --export-height=$size --export-background-opacity=0 "$svg" --export-filename="assets/icons/${basename}-${size}.png"; done; done
2025-08-29 11:04:16 +02:00
am0
a617d82716 chore(package.json): początek dodawania abstrakcji w build-time
- wprowadzenie rozróżnienia w buildach dla firefox i chrome
- dodanie @types/chrome do rozpoznania przez typescript
2025-08-11 17:58:30 +02:00
7 changed files with 339 additions and 1 deletions

7
.gitignore vendored
View File

@ -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/

54
lib/browser-api/chrome.ts Normal file
View File

@ -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,
},
};

View File

@ -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,
},
};

27
lib/browser-api/index.ts Normal file
View File

@ -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';

124
lib/browser-api/types.ts Normal file
View File

@ -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: ['<all_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<Tab[]>;
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<Cookie[]>;
remove(details: CookieRemove): Promise<Cookie | null>;
};
// Extension API
extension: {
getBackgroundPage(): Window | null;
};
// Windows API
windows: {
WINDOW_ID_CURRENT: number;
};
}

63
package-lock.json generated
View File

@ -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",

View File

@ -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",