refactor(icons): remove color injection; set emphasis stroke directly in SVG\n\n- stroke set to #F5A623 in icons/file-search.svg\n- build script now rasterizes SVG as-is using ImageMagick only\n- docs updated to reflect new flow

This commit is contained in:
Jordan Wages 2025-08-24 01:47:13 -05:00
commit 36bef61f2e
3 changed files with 13 additions and 44 deletions

View file

@ -14,14 +14,9 @@ Run `npm run build` (or `npm run build:icons`) to regenerate. The manifest is wi
Notes Notes
----- -----
- Source: `icons/file-search.svg` uses `stroke="currentColor"`. - Source: `icons/file-search.svg` defines the exact stroke color (an emphasis color) directly in the SVG.
- The build script replaces `currentColor` with configured colors and rasterizes with a transparent background. It also injects explicit `stroke`/`fill` on each path for better compatibility across renderers. - The build script does not inject or replace colors; it rasterizes the SVG as-is to transparent PNGs using ImageMagick.
- Default stroke colors use the project emphasis palette: - To change the icon color, edit the `stroke="#..."` attribute in `icons/file-search.svg`.
- Addon icons (48/96/128): Primary 2 (deep) `#223544`.
- Toolbar icons (16/32): Primary 1 (light) `#5AC3D6`.
- Customize via env vars when building:
- `ICON_COLOR_ADDON` (48/96/128); default `#223544`.
- `ICON_COLOR_TOOLBAR` (16/32); default `#5AC3D6`.
- Firefox does not require .ico; PNG is recommended. - Firefox does not require .ico; PNG is recommended.
- Theme variants can be added later via `browser_action.theme_icons`. - Theme variants can be added later via `browser_action.theme_icons` if desired.
- Rasterizer: uses ImageMagick only (`magick` or `convert`). Ensure your ImageMagick build supports reading SVG (via `librsvg` or compatible delegate). - Rasterizer: uses ImageMagick only (`magick` or `convert`). Ensure your ImageMagick build supports reading SVG (via `librsvg` or a compatible delegate).

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" data-attribution="cc0-icons" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="#F5A623" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.8" data-attribution="cc0-icons" viewBox="0 0 24 24">
<path d="M13.2 16.2 16 19m-2-5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm0-12v6h5"/> <path d="M13.2 16.2 16 19m-2-5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm0-12v6h5"/>
<path d="M15 2H6.5c-1.09 0-2 .91-2 2v16c0 1.09.91 2 2 2h11c1.09 0 2-.91 2-2V7.5L15 2Z"/> <path d="M15 2H6.5c-1.09 0-2 .91-2 2v16c0 1.09.91 2 2 2h11c1.09 0 2-.91 2-2V7.5L15 2Z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 380 B

Before After
Before After

View file

@ -1,15 +1,10 @@
#!/usr/bin/env node #!/usr/bin/env node
/* /*
Generates extension and toolbar PNG icons from the base SVG with transparent Generates extension and toolbar PNG icons from the base SVG with transparent
background and configurable stroke colors. Requires ImageMagick (`magick`). background. Requires ImageMagick (`magick` or `convert`).
Theme defaults (aligned with project palette): The SVG defines its own stroke color (set directly in icons/file-search.svg).
Primary 2 (deep): #223544 add-on icon strokes (default) To change colors, edit the SVG; the script does not inject or replace colors.
Primary 1 (light): #5AC3D6 toolbar icon strokes (default)
Override via environment variables (optional):
ICON_COLOR_ADDON hex color for add-on icons (48/96/128). Default: #223544
ICON_COLOR_TOOLBAR hex color for toolbar icons (16/32). Default: #5AC3D6
Usage: Usage:
node scripts/build-icons.js node scripts/build-icons.js
@ -25,9 +20,6 @@ const SRC_SVG = path.join(ICONS_DIR, 'file-search.svg');
const ADDON_SIZES = [48, 96, 128]; const ADDON_SIZES = [48, 96, 128];
const TOOLBAR_SIZES = [16, 32]; const TOOLBAR_SIZES = [16, 32];
const COLOR_ADDON = process.env.ICON_COLOR_ADDON || '#223544';
const COLOR_TOOLBAR = process.env.ICON_COLOR_TOOLBAR || '#5AC3D6';
function ensureMagick() { function ensureMagick() {
try { try {
let res = spawnSync('magick', ['-version'], { stdio: 'ignore' }); let res = spawnSync('magick', ['-version'], { stdio: 'ignore' });
@ -46,22 +38,6 @@ function readSvg() {
return fs.readFileSync(SRC_SVG, 'utf8'); return fs.readFileSync(SRC_SVG, 'utf8');
} }
function colorize(svg, color) {
// Replace currentColor with explicit hex color and inject explicit stroke attributes on each path
let s = svg.replace(/currentColor/gi, color);
// Ensure each <path> has explicit stroke and fill to avoid inheritance issues in some renderers
s = s.replace(/<path\b([^>]*?)\/>/g, (m, attrs) => {
let a = attrs;
if (!/\bstroke\s*=/.test(a)) a = ` stroke=\"${color}\"` + a;
if (!/\bstroke-width\s*=/.test(a)) a = ` stroke-width=\"1.8\"` + a;
if (!/\bstroke-linecap\s*=/.test(a)) a = ` stroke-linecap=\"round\"` + a;
if (!/\bstroke-linejoin\s*=/.test(a)) a = ` stroke-linejoin=\"round\"` + a;
if (!/\bfill\s*=/.test(a)) a = ` fill=\"none\"` + a;
return `<path${a}/>`;
});
return s;
}
function rasterize(magickBin, svgString, size, outPath) { function rasterize(magickBin, svgString, size, outPath) {
const args = ['-background', 'none', '-density', '384', 'svg:-', '-resize', `${size}x${size}`, outPath]; const args = ['-background', 'none', '-density', '384', 'svg:-', '-resize', `${size}x${size}`, outPath];
const proc = spawnSync(magickBin, args, { input: svgString, stdio: ['pipe', 'inherit', 'inherit'] }); const proc = spawnSync(magickBin, args, { input: svgString, stdio: ['pipe', 'inherit', 'inherit'] });
@ -81,19 +57,17 @@ function main() {
const base = readSvg(); const base = readSvg();
// Add-on icons // Add-on icons (use SVG colors as-is)
const addonSvg = colorize(base, COLOR_ADDON);
for (const s of ADDON_SIZES) { for (const s of ADDON_SIZES) {
const out = path.join(ICONS_DIR, `icon-${s}.png`); const out = path.join(ICONS_DIR, `icon-${s}.png`);
rasterize(magick, addonSvg, s, out); rasterize(magick, base, s, out);
console.log(`Generated ${path.relative(REPO_ROOT, out)}`); console.log(`Generated ${path.relative(REPO_ROOT, out)}`);
} }
// Toolbar icons // Toolbar icons (use SVG colors as-is)
const toolbarSvg = colorize(base, COLOR_TOOLBAR);
for (const s of TOOLBAR_SIZES) { for (const s of TOOLBAR_SIZES) {
const out = path.join(ICONS_DIR, `icon-${s}.png`); const out = path.join(ICONS_DIR, `icon-${s}.png`);
rasterize(magick, toolbarSvg, s, out); rasterize(magick, base, s, out);
console.log(`Generated ${path.relative(REPO_ROOT, out)}`); console.log(`Generated ${path.relative(REPO_ROOT, out)}`);
} }
} }