build(icons): generate toolbar/add-on PNGs from SVG with transparent background; configurable colors; stop tracking PNGs and ignore outputs
This commit is contained in:
		
					parent
					
						
							
								f0120c0d2f
							
						
					
				
			
			
				commit
				
					
						73544334c9
					
				
			
		
					 11 changed files with 111 additions and 17 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -8,3 +8,6 @@ releases/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Web-ext/AMO signing upload cache (not needed in repo)
 | 
					# Web-ext/AMO signing upload cache (not needed in repo)
 | 
				
			||||||
.amo-upload-uuid
 | 
					.amo-upload-uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Generated icons
 | 
				
			||||||
 | 
					icons/icon-*.png
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
Icon assets
 | 
					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):
 | 
					- Toolbar (browser_action → default_icon):
 | 
				
			||||||
  - icons/icon-16.png
 | 
					  - 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
 | 
					Notes
 | 
				
			||||||
-----
 | 
					-----
 | 
				
			||||||
- Use the same artwork at each size; keep transparent backgrounds.
 | 
					- Source: `icons/file-search.svg` uses `stroke="currentColor"`.
 | 
				
			||||||
- Source: a 128×128 PNG is perfect; export downscaled versions for 96/48/32/16.
 | 
					- 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.
 | 
					- 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.
 | 
					- Theme variants can be added later via `browser_action.theme_icons`.
 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 315 B  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 298 B  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 299 B  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 300 B  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 306 B  | 
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  "manifest_version": 2,
 | 
					  "manifest_version": 2,
 | 
				
			||||||
  "name": "Archive.org Link Grabber",
 | 
					  "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.",
 | 
					  "description": "Filter and export archive.org /download links; copy or send to aria2 RPC.",
 | 
				
			||||||
  "applications": {
 | 
					  "applications": {
 | 
				
			||||||
    "gecko": {
 | 
					    "gecko": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,8 @@
 | 
				
			||||||
  "description": "Firefox WebExtension to filter archive.org /download links and copy/send to aria2.",
 | 
					  "description": "Firefox WebExtension to filter archive.org /download links and copy/send to aria2.",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "dev": "web-ext run --start-url https://archive.org --source-dir .",
 | 
					    "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",
 | 
					    "lint": "echo 'Add ESLint config to enable' && exit 0",
 | 
				
			||||||
    "format": "echo 'Add Prettier config to enable' && exit 0",
 | 
					    "format": "echo 'Add Prettier config to enable' && exit 0",
 | 
				
			||||||
    "test": "echo 'No tests yet' && exit 0",
 | 
					    "test": "echo 'No tests yet' && exit 0",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,6 +37,15 @@
 | 
				
			||||||
              "strict_min_version": "91.0"
 | 
					              "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"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										87
									
								
								scripts/build-icons.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								scripts/build-icons.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue