diff --git a/.gitignore b/.gitignore index fd6a0b3..751d3a0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ node_modules/ # Ignore all release artifacts except updates.json (tracked) releases/* !releases/updates.json - + # Web-ext/AMO signing upload cache (not needed in repo) .amo-upload-uuid + +# Generated icons +icons/icon-*.png diff --git a/icons/README.md b/icons/README.md index e485696..ec0cb99 100644 --- a/icons/README.md +++ b/icons/README.md @@ -1,7 +1,8 @@ Icon assets =========== -Place the final PNGs for the add-on icon here. The manifest is wired to use: +PNG icons are generated from `file-search.svg` during the build. +Run `npm run build` (or `npm run build:icons`) to regenerate. The manifest is wired to use: - Toolbar (browser_action → default_icon): - icons/icon-16.png @@ -13,17 +14,10 @@ Place the final PNGs for the add-on icon here. The manifest is wired to use: Notes ----- -- Use the same artwork at each size; keep transparent backgrounds. -- Source: a 128×128 PNG is perfect; export downscaled versions for 96/48/32/16. +- Source: `icons/file-search.svg` uses `stroke="currentColor"`. +- The build script replaces `currentColor` with configured colors and rasterizes with a transparent background. +- Customize colors via env vars: + - `ICON_COLOR_ADDON` (48/96/128); default `#111827`. + - `ICON_COLOR_TOOLBAR` (16/32); default `#111827`. - Firefox does not require .ico; PNG is recommended. -- If you later want theme-specific toolbar icons, you can add `browser_action.theme_icons` with light/dark variants. - -Quick export (ImageMagick) -------------------------- -```bash -magick file-search.svg -resize 128x128 icon-128.png -magick file-search.svg -resize 96x96 icon-96.png -magick file-search.svg -resize 48x48 icon-48.png -magick file-search.svg -resize 32x32 icon-32.png -magick file-search.svg -resize 16x16 icon-16.png -``` +- Theme variants can be added later via `browser_action.theme_icons`. diff --git a/icons/icon-128.png b/icons/icon-128.png deleted file mode 100644 index 80cd7c2..0000000 Binary files a/icons/icon-128.png and /dev/null differ diff --git a/icons/icon-16.png b/icons/icon-16.png deleted file mode 100644 index 6a41774..0000000 Binary files a/icons/icon-16.png and /dev/null differ diff --git a/icons/icon-32.png b/icons/icon-32.png deleted file mode 100644 index ed0a9e4..0000000 Binary files a/icons/icon-32.png and /dev/null differ diff --git a/icons/icon-48.png b/icons/icon-48.png deleted file mode 100644 index f9b8d58..0000000 Binary files a/icons/icon-48.png and /dev/null differ diff --git a/icons/icon-96.png b/icons/icon-96.png deleted file mode 100644 index 50b2637..0000000 Binary files a/icons/icon-96.png and /dev/null differ diff --git a/manifest.json b/manifest.json index 4d36695..8090c27 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "Archive.org Link Grabber", - "version": "0.3.1", + "version": "0.3.2", "description": "Filter and export archive.org /download links; copy or send to aria2 RPC.", "applications": { "gecko": { diff --git a/package.json b/package.json index dcc6115..3c135d7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "description": "Firefox WebExtension to filter archive.org /download links and copy/send to aria2.", "scripts": { "dev": "web-ext run --start-url https://archive.org --source-dir .", - "build": "web-ext build -o -a dist", + "build:icons": "node scripts/build-icons.js", + "build": "npm run build:icons && web-ext build -o -a dist", "lint": "echo 'Add ESLint config to enable' && exit 0", "format": "echo 'Add Prettier config to enable' && exit 0", "test": "echo 'No tests yet' && exit 0", diff --git a/releases/updates.json b/releases/updates.json index 8bac4a6..fc42a68 100644 --- a/releases/updates.json +++ b/releases/updates.json @@ -37,6 +37,15 @@ "strict_min_version": "91.0" } } + }, + { + "version": "0.3.2", + "update_link": "https://add-ons.jordanwages.com/archive-org-link-grabber/abf5f9638af544919be4-0.3.2.xpi", + "applications": { + "gecko": { + "strict_min_version": "91.0" + } + } } ] } diff --git a/scripts/build-icons.js b/scripts/build-icons.js new file mode 100644 index 0000000..dc9ef38 --- /dev/null +++ b/scripts/build-icons.js @@ -0,0 +1,87 @@ +#!/usr/bin/env node +/* + Generates extension and toolbar PNG icons from the base SVG with transparent + background and configurable stroke colors. Requires ImageMagick (`magick`). + + Config via environment variables (optional): + ICON_COLOR_ADDON – hex color for add-on icons (48/96/128). Default: #111827 + ICON_COLOR_TOOLBAR – hex color for toolbar icons (16/32). Default: #111827 + + Usage: + node scripts/build-icons.js +*/ +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const REPO_ROOT = path.join(__dirname, '..'); +const ICONS_DIR = path.join(REPO_ROOT, 'icons'); +const SRC_SVG = path.join(ICONS_DIR, 'file-search.svg'); + +const ADDON_SIZES = [48, 96, 128]; +const TOOLBAR_SIZES = [16, 32]; + +const COLOR_ADDON = process.env.ICON_COLOR_ADDON || '#111827'; +const COLOR_TOOLBAR = process.env.ICON_COLOR_TOOLBAR || '#111827'; + +function ensureMagick() { + const which = spawnSync('bash', ['-lc', 'command -v magick || command -v convert']); + if (which.status !== 0) return null; + const bin = which.stdout.toString().trim(); + return bin || null; +} + +function readSvg() { + if (!fs.existsSync(SRC_SVG)) { + console.error(`Base SVG not found: ${path.relative(REPO_ROOT, SRC_SVG)}`); + process.exit(1); + } + return fs.readFileSync(SRC_SVG, 'utf8'); +} + +function colorize(svg, color) { + // Replace currentColor with explicit hex color. Keep case-insensitive safety. + return svg.replace(/currentColor/gi, color); +} + +function rasterize(magickBin, svgString, size, outPath) { + // Use ImageMagick, transparent background, high density for crisp vector rasterization. + const proc = spawnSync('bash', ['-lc', `${magickBin} -background none -density 384 svg:- -resize ${size}x${size} ${outPath}`], { + input: svgString, + stdio: ['pipe', 'inherit', 'inherit'], + }); + if (proc.status !== 0) { + console.error(`Failed to generate ${outPath}`); + process.exit(proc.status || 1); + } +} + +function main() { + const magick = ensureMagick(); + if (!magick) { + console.error('ImageMagick not found. Please install it or adjust this script to use inkscape/rsvg-convert.'); + process.exit(1); + } + if (!fs.existsSync(ICONS_DIR)) fs.mkdirSync(ICONS_DIR, { recursive: true }); + + const base = readSvg(); + + // Add-on icons + const addonSvg = colorize(base, COLOR_ADDON); + for (const s of ADDON_SIZES) { + const out = path.join(ICONS_DIR, `icon-${s}.png`); + rasterize(magick, addonSvg, s, out); + console.log(`Generated ${path.relative(REPO_ROOT, out)}`); + } + + // Toolbar icons + const toolbarSvg = colorize(base, COLOR_TOOLBAR); + for (const s of TOOLBAR_SIZES) { + const out = path.join(ICONS_DIR, `icon-${s}.png`); + rasterize(magick, toolbarSvg, s, out); + console.log(`Generated ${path.relative(REPO_ROOT, out)}`); + } +} + +main(); +