From fbd8a555ec015f4402ddbe17893444872858b1a2 Mon Sep 17 00:00:00 2001 From: Andrew Zambazos <62979495+Bobbybear007@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:16:51 +1200 Subject: [PATCH] Refactor SVGs to use CSS masks Replace inline SVG markup with external icon files using CSS mask-based rendering. This approach reduces HTML duplication, enables dynamic color tinting via currentColor, and improves maintainability by centralizing icon definitions. Updates favicon rendering in chrome.js, icon styling in CSS files, and converts icon elements across 404, insecure, and settings pages. Also updates settings page favicon and GitHub link URL. --- assets/icons/alert-circle.svg | 5 +++++ assets/icons/github.svg | 3 +++ assets/icons/help.svg | 3 +++ assets/icons/layers.svg | 7 +++++++ assets/icons/settings.svg | 16 ++++++++++++++++ ui/assets/icons/alert-circle.svg | 17 +++++++++++++++++ ui/assets/icons/github.svg | 1 + ui/assets/icons/help.svg | 17 +++++++++++++++++ ui/assets/icons/settings.svg | 16 ++++++++++++++++ ui/assets/icons/shield-alert.svg | 17 +++++++++++++++++ ui/css/chrome.css | 9 +++++++++ ui/css/settings.css | 10 ++++++++-- ui/js/chrome.js | 19 +++++++++++++++++++ ui/pages/404.html | 7 ++++--- ui/pages/insecure.html | 6 ++++-- ui/pages/settings.html | 16 +++++----------- 16 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 assets/icons/alert-circle.svg create mode 100644 assets/icons/github.svg create mode 100644 assets/icons/help.svg create mode 100644 assets/icons/layers.svg create mode 100644 assets/icons/settings.svg create mode 100644 ui/assets/icons/alert-circle.svg create mode 100644 ui/assets/icons/github.svg create mode 100644 ui/assets/icons/help.svg create mode 100644 ui/assets/icons/settings.svg create mode 100644 ui/assets/icons/shield-alert.svg diff --git a/assets/icons/alert-circle.svg b/assets/icons/alert-circle.svg new file mode 100644 index 0000000..899a535 --- /dev/null +++ b/assets/icons/alert-circle.svg @@ -0,0 +1,5 @@ + diff --git a/assets/icons/github.svg b/assets/icons/github.svg new file mode 100644 index 0000000..24e8e90 --- /dev/null +++ b/assets/icons/github.svg @@ -0,0 +1,3 @@ + diff --git a/assets/icons/help.svg b/assets/icons/help.svg new file mode 100644 index 0000000..7498b89 --- /dev/null +++ b/assets/icons/help.svg @@ -0,0 +1,3 @@ + diff --git a/assets/icons/layers.svg b/assets/icons/layers.svg new file mode 100644 index 0000000..ed2453e --- /dev/null +++ b/assets/icons/layers.svg @@ -0,0 +1,7 @@ + diff --git a/assets/icons/settings.svg b/assets/icons/settings.svg new file mode 100644 index 0000000..4043d11 --- /dev/null +++ b/assets/icons/settings.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/ui/assets/icons/alert-circle.svg b/ui/assets/icons/alert-circle.svg new file mode 100644 index 0000000..003b9f3 --- /dev/null +++ b/ui/assets/icons/alert-circle.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/ui/assets/icons/github.svg b/ui/assets/icons/github.svg new file mode 100644 index 0000000..f449bb1 --- /dev/null +++ b/ui/assets/icons/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/assets/icons/help.svg b/ui/assets/icons/help.svg new file mode 100644 index 0000000..98d2fa0 --- /dev/null +++ b/ui/assets/icons/help.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/ui/assets/icons/settings.svg b/ui/assets/icons/settings.svg new file mode 100644 index 0000000..4043d11 --- /dev/null +++ b/ui/assets/icons/settings.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/ui/assets/icons/shield-alert.svg b/ui/assets/icons/shield-alert.svg new file mode 100644 index 0000000..17cc972 --- /dev/null +++ b/ui/assets/icons/shield-alert.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/ui/css/chrome.css b/ui/css/chrome.css index eb732eb..2fbaa33 100644 --- a/ui/css/chrome.css +++ b/ui/css/chrome.css @@ -165,6 +165,15 @@ button:disabled { opacity: 1; } +/* Local Lucide/Octicons SVGs: paint with tab text color */ +.tab-favicon.has-favicon.tinted-icon { + background: currentColor; + border-radius: 3px; + opacity: 1; + -webkit-mask: var(--tab-icon-mask) center / contain no-repeat; + mask: var(--tab-icon-mask) center / contain no-repeat; +} + .tab-favicon.empty { width: 13px; height: 13px; diff --git a/ui/css/settings.css b/ui/css/settings.css index 1d65a40..bf88ae7 100644 --- a/ui/css/settings.css +++ b/ui/css/settings.css @@ -710,11 +710,17 @@ input[type="color"] { .github-btn:hover, .help-btn:hover { background: var(--surface-hover); } -.github-btn svg, .help-btn svg { +.github-btn .btn-icon, .help-btn .btn-icon { width: 16px; height: 16px; - fill: currentColor; + flex-shrink: 0; + display: inline-block; + background-color: currentColor; + -webkit-mask: var(--btn-icon-mask) center / contain no-repeat; + mask: var(--btn-icon-mask) center / contain no-repeat; } +.btn-icon-github { --btn-icon-mask: url("../assets/icons/github.svg"); } +.btn-icon-help { --btn-icon-mask: url("../assets/icons/help.svg"); } .about-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; } /* Debug info */ diff --git a/ui/js/chrome.js b/ui/js/chrome.js index 99b5c3d..2134821 100644 --- a/ui/js/chrome.js +++ b/ui/js/chrome.js @@ -133,16 +133,35 @@ function postCommand(command, payload = '') { } } +function isTintableLocalIcon(url) { + // Lucide/Octicons under assets/icons use currentColor — tint via CSS mask. + // Branding SVGs keep their own colors and stay as . + try { + const path = new URL(url, window.location.href).pathname.replace(/\\/g, '/').toLowerCase(); + return path.includes('/assets/icons/') && path.endsWith('.svg'); + } catch { + const normalized = String(url).replace(/\\/g, '/').toLowerCase(); + return normalized.includes('/assets/icons/') && normalized.endsWith('.svg'); + } +} + function renderFavicon(favicon, tab) { const url = (tab.favicon || '').trim(); favicon.className = 'tab-favicon'; favicon.textContent = ''; + favicon.style.removeProperty('--tab-icon-mask'); if (!url) { favicon.classList.add('empty'); return; } + if (isTintableLocalIcon(url)) { + favicon.classList.add('has-favicon', 'tinted-icon'); + favicon.style.setProperty('--tab-icon-mask', `url("${url.replace(/\\/g, '/').replace(/"/g, '\\"')}")`); + return; + } + const image = document.createElement('img'); image.alt = ''; image.decoding = 'async'; diff --git a/ui/pages/404.html b/ui/pages/404.html index 08a6b46..7d2f88b 100644 --- a/ui/pages/404.html +++ b/ui/pages/404.html @@ -13,12 +13,13 @@ .card { max-width:780px; width:100%; background:linear-gradient(145deg,#1c1c1c,#242424); border:1px solid #2c2c2c; border-radius:20px; padding:40px 46px 48px; box-shadow:0 8px 28px -6px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,0.04); position:relative; overflow:hidden; } .card:before { content:""; position:absolute; inset:0; background:radial-gradient(circle at 18% 15%,rgba(255,255,255,.08),transparent 55%), radial-gradient(circle at 82% 78%,rgba(255,255,255,.05),transparent 60%); pointer-events:none; } h1 { font-size: clamp(1.9rem, 2.6vw, 2.6rem); margin:0 0 12px; letter-spacing:-.5px; display:flex; align-items:center; gap:.6rem; } - h1 svg { width:28px; height:28px; flex-shrink:0; } + h1 img.page-icon, + h1 .page-icon { width:28px; height:28px; flex-shrink:0; display:inline-block; background-color:currentColor; -webkit-mask:url("../assets/icons/alert-circle.svg") center / contain no-repeat; mask:url("../assets/icons/alert-circle.svg") center / contain no-repeat; } h1 span.badge { font-size:12px; letter-spacing:1px; padding:4px 8px; border:1px solid var(--danger); color:var(--danger); border-radius:999px; text-transform:uppercase; background:rgba(220,38,38,0.1); } p.lede { font-size:1.05rem; line-height:1.55; margin:0 0 22px; color:var(--muted); } code { background:#252525; padding:3px 6px; border-radius:6px; font-size:.9rem; color:#e0e0e0; } .url-box { font-family:monospace; font-size:.92rem; padding:10px 12px; background:#181818; border:1px solid #2a2a2a; border-radius:10px; word-break:break-all; margin:0 0 22px; display:flex; align-items:center; gap:.75rem; } - .url-box svg { flex:0 0 auto; width:22px; height:22px; stroke:var(--danger); } + .url-box img { flex:0 0 auto; width:22px; height:22px; } ul { margin:0 0 26px 1.1rem; padding:0; line-height:1.5; color:var(--muted); } ul li { margin-bottom:6px; } .actions { display:flex; flex-wrap:wrap; gap:14px; } @@ -37,7 +38,7 @@

- + Page Not Found 404

The page you're looking for doesn't exist or has been moved. You've warped into an unknown sector of the web.

diff --git a/ui/pages/insecure.html b/ui/pages/insecure.html index 4d621ce..2e0da86 100644 --- a/ui/pages/insecure.html +++ b/ui/pages/insecure.html @@ -13,11 +13,13 @@ .card { max-width:780px; width:100%; background:linear-gradient(145deg,#1c1c1c,#242424); border:1px solid #2c2c2c; border-radius:20px; padding:40px 46px 48px; box-shadow:0 8px 28px -6px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,0.04); position:relative; overflow:hidden; } .card:before { content:""; position:absolute; inset:0; background:radial-gradient(circle at 18% 15%,rgba(255,255,255,.08),transparent 55%), radial-gradient(circle at 82% 78%,rgba(255,255,255,.05),transparent 60%); pointer-events:none; } h1 { font-size: clamp(1.9rem, 2.6vw, 2.6rem); margin:0 0 12px; letter-spacing:-.5px; display:flex; align-items:center; gap:.6rem; } + h1 img.page-icon, + h1 .page-icon { width:28px; height:28px; flex-shrink:0; display:inline-block; background-color:currentColor; -webkit-mask:url("../assets/icons/shield-alert.svg") center / contain no-repeat; mask:url("../assets/icons/shield-alert.svg") center / contain no-repeat; } h1 span.badge { font-size:12px; letter-spacing:1px; padding:4px 8px; border:1px solid var(--warn); color:var(--warn); border-radius:999px; text-transform:uppercase; background:rgba(217,119,6,0.1); } p.lede { font-size:1.05rem; line-height:1.55; margin:0 0 22px; color:var(--muted); } code { background:#252525; padding:3px 6px; border-radius:6px; font-size:.9rem; color:#e0e0e0; } .url-box { font-family:monospace; font-size:.92rem; padding:10px 12px; background:#181818; border:1px solid #2a2a2a; border-radius:10px; word-break:break-all; margin:0 0 22px; display:flex; align-items:center; gap:.75rem; } - .url-box svg { flex:0 0 auto; width:22px; height:22px; stroke:var(--warn); } + .url-box img { flex:0 0 auto; width:22px; height:22px; } ul { margin:0 0 26px 1.1rem; padding:0; line-height:1.5; color:var(--muted); } ul li { margin-bottom:6px; } .actions { display:flex; flex-wrap:wrap; gap:14px; } @@ -37,7 +39,7 @@

- + Connection Not Secure http

You’re about to visit a page using HTTP (unencrypted). Information you send or view can potentially be intercepted or modified. If this is a site you trust and you understand the risks, you can continue anyway.

diff --git a/ui/pages/settings.html b/ui/pages/settings.html index 0f83b45..be2bea4 100644 --- a/ui/pages/settings.html +++ b/ui/pages/settings.html @@ -4,7 +4,7 @@ Settings - + @@ -306,18 +306,12 @@