detached d3c3c1d

homepage: ensure perfect circular favicon via wrapper chip (20x20) and center 16px icon; align history row center to avoid distortion

commit
d3c3c1d989a4cd9f46ec97cde28ebc8a1f9d5c4e
author
bamen · · 2025-09-09 16:05 UTC
committer
bamen · · 2025-09-09 16:41 UTC
parent
c914750
signature
unsigned
2 files · +16 -10
M frontend/src/utils/dom.ts +7 -4
@@ -78,14 +78,17 @@ export class DOMRenderer {
7878 const line = document.createElement('div');
7979 line.className = 'history-line';
8080
81- // Favicon chip
81+ // Favicon chip (wrapper ensures perfect circle sizing)
82+ const iconWrap = document.createElement('div');
83+ iconWrap.className = 'history-favicon-chip';
8284 const icon = document.createElement('img');
83- icon.className = 'history-favicon';
85+ icon.className = 'history-favicon-img';
8486 icon.width = 16; icon.height = 16;
8587 icon.loading = 'lazy';
8688 icon.referrerPolicy = 'no-referrer';
8789 icon.src = this.buildFaviconURL(item.url);
88- icon.addEventListener('error', () => { icon.style.display = 'none'; });
90+ icon.addEventListener('error', () => { iconWrap.style.display = 'none'; });
91+ iconWrap.appendChild(icon);
8992
9093 const titleEl = document.createElement('span');
9194 titleEl.className = 'history-title';
@@ -107,7 +110,7 @@ export class DOMRenderer {
107110 urlEl.className = 'history-url';
108111 urlEl.textContent = item.url;
109112
110- line.appendChild(icon);
113+ line.appendChild(iconWrap);
111114 line.appendChild(titleEl);
112115 line.appendChild(sep1);
113116 line.appendChild(domainEl);
@@ -78,14 +78,17 @@ export class DOMRenderer {
78 const line = document.createElement('div');78 const line = document.createElement('div');
79 line.className = 'history-line';79 line.className = 'history-line';
80 80
81- // Favicon chip81+ // Favicon chip (wrapper ensures perfect circle sizing)
82+ const iconWrap = document.createElement('div');
83+ iconWrap.className = 'history-favicon-chip';
82 const icon = document.createElement('img');84 const icon = document.createElement('img');
83- icon.className = 'history-favicon';85+ icon.className = 'history-favicon-img';
84 icon.width = 16; icon.height = 16;86 icon.width = 16; icon.height = 16;
85 icon.loading = 'lazy';87 icon.loading = 'lazy';
86 icon.referrerPolicy = 'no-referrer';88 icon.referrerPolicy = 'no-referrer';
87 icon.src = this.buildFaviconURL(item.url);89 icon.src = this.buildFaviconURL(item.url);
88- icon.addEventListener('error', () => { icon.style.display = 'none'; });90+ icon.addEventListener('error', () => { iconWrap.style.display = 'none'; });
91+ iconWrap.appendChild(icon);
89 92
90 const titleEl = document.createElement('span');93 const titleEl = document.createElement('span');
91 titleEl.className = 'history-title';94 titleEl.className = 'history-title';
@@ -107,7 +110,7 @@ export class DOMRenderer {
107 urlEl.className = 'history-url';110 urlEl.className = 'history-url';
108 urlEl.textContent = item.url;111 urlEl.textContent = item.url;
109 112
110- line.appendChild(icon);113+ line.appendChild(iconWrap);
111 line.appendChild(titleEl);114 line.appendChild(titleEl);
112 line.appendChild(sep1);115 line.appendChild(sep1);
113 line.appendChild(domainEl);116 line.appendChild(domainEl);
M frontend/src/utils/html-builder.ts +9 -6
@@ -109,21 +109,24 @@ export class HTMLBuilder {
109109 display: flex;
110110 gap: 0.5rem;
111111 white-space: nowrap;
112- align-items: baseline;
112+ align-items: center;
113113 overflow: hidden;
114114 width: 100%;
115115 min-width: 0; /* allow flex children to shrink */
116116 }
117-
118- .history-favicon {
117+ .history-favicon-chip {
119118 flex: 0 0 20px;
120- width: 16px; height: 16px;
121- padding: 2px;
122- box-sizing: content-box;
119+ width: 20px; height: 20px;
123120 border-radius: 50%;
124121 background: #ccc;
125122 border: 1px solid rgba(0,0,0,.12);
126123 box-shadow: 0 1px 2px rgba(0,0,0,.12);
124+ display: flex;
125+ align-items: center;
126+ justify-content: center;
127+ }
128+ .history-favicon-img {
129+ width: 16px; height: 16px;
127130 filter: brightness(1.06) contrast(1.03);
128131 image-rendering: -webkit-optimize-contrast;
129132 }
@@ -109,21 +109,24 @@ export class HTMLBuilder {
109 display: flex;109 display: flex;
110 gap: 0.5rem;110 gap: 0.5rem;
111 white-space: nowrap;111 white-space: nowrap;
112- align-items: baseline;112+ align-items: center;
113 overflow: hidden;113 overflow: hidden;
114 width: 100%;114 width: 100%;
115 min-width: 0; /* allow flex children to shrink */115 min-width: 0; /* allow flex children to shrink */
116 }116 }
117-117+ .history-favicon-chip {
118- .history-favicon {
119 flex: 0 0 20px;118 flex: 0 0 20px;
120- width: 16px; height: 16px;119+ width: 20px; height: 20px;
121- padding: 2px;
122- box-sizing: content-box;
123 border-radius: 50%;120 border-radius: 50%;
124 background: #ccc;121 background: #ccc;
125 border: 1px solid rgba(0,0,0,.12);122 border: 1px solid rgba(0,0,0,.12);
126 box-shadow: 0 1px 2px rgba(0,0,0,.12);123 box-shadow: 0 1px 2px rgba(0,0,0,.12);
124+ display: flex;
125+ align-items: center;
126+ justify-content: center;
127+ }
128+ .history-favicon-img {
129+ width: 16px; height: 16px;
127 filter: brightness(1.06) contrast(1.03);130 filter: brightness(1.06) contrast(1.03);
128 image-rendering: -webkit-optimize-contrast;131 image-rendering: -webkit-optimize-contrast;
129 }132 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close