@@ -20,7 +20,8 @@ const DEBOUNCE_MS = 300
2020/**
2121 * Find UI is loaded in a separate BrowserView (see `findInPageOverlayHost.ts`) so
2222 * `findInPage` on the page webContents does not search the query in this input.
23- * Shadow DOM keeps chrome text minimal. Match counts are not shown.
23+ * Shadow DOM keeps chrome text minimal. Match count / current index come from
24+ * `found-in-page` forwarded as `onFindInPageResult`.
2425 *
2526 * Chromium moves focus to the matched text in the **page** webContents after
2627 * `findInPage`, so the overlay stops receiving keystrokes unless we put focus back
@@ -49,6 +50,11 @@ export function setupDesktopFindInPageBar (electronApi: IPCMainExposed): void {
4950 input . spellcheck = false
5051 input . setAttribute ( 'aria-label' , 'Find in page' )
5152
53+ const matchCount = document . createElement ( 'span' )
54+ matchCount . className = 'match-count'
55+ matchCount . setAttribute ( 'aria-live' , 'polite' )
56+ matchCount . setAttribute ( 'aria-atomic' , 'true' )
57+
5258 const nav = document . createElement ( 'div' )
5359 nav . className = 'nav'
5460 nav . setAttribute ( 'role' , 'group' )
@@ -76,6 +82,7 @@ export function setupDesktopFindInPageBar (electronApi: IPCMainExposed): void {
7682 closeBtn . title = 'Close'
7783
7884 root . appendChild ( input )
85+ root . appendChild ( matchCount )
7986 root . appendChild ( nav )
8087 root . appendChild ( closeBtn )
8188 shadow . appendChild ( style )
@@ -89,6 +96,19 @@ export function setupDesktopFindInPageBar (electronApi: IPCMainExposed): void {
8996 return input . value . trim ( )
9097 }
9198
99+ function clearMatchCount ( ) : void {
100+ matchCount . textContent = ''
101+ matchCount . removeAttribute ( 'title' )
102+ }
103+
104+ function describeMatchCount ( matches : number , activeOrdinal : number ) : { label : string , title : string } {
105+ if ( matches <= 0 ) {
106+ return { label : '0/0' , title : 'No matches' }
107+ }
108+ const cur = activeOrdinal > 0 ? Math . min ( activeOrdinal , matches ) : 1
109+ return { label : `${ cur } /${ matches } ` , title : `Match ${ cur } of ${ matches } ` }
110+ }
111+
92112 function updateNavState ( ) : void {
93113 const q = getQuery ( )
94114 prevBtn . disabled = q === ''
@@ -114,6 +134,7 @@ export function setupDesktopFindInPageBar (electronApi: IPCMainExposed): void {
114134 function hide ( ) : void {
115135 visible = false
116136 host . style . display = 'none'
137+ clearMatchCount ( )
117138 prevBtn . disabled = true
118139 nextBtn . disabled = true
119140 try {
@@ -165,6 +186,7 @@ export function setupDesktopFindInPageBar (electronApi: IPCMainExposed): void {
165186 debounceTimer = undefined
166187 const q = getQuery ( )
167188 if ( q === '' ) {
189+ clearMatchCount ( )
168190 void electronApi . stopFindInPage ( 'clearSelection' ) . catch ( ( ) => { } )
169191 updateNavState ( )
170192 return
@@ -226,6 +248,20 @@ export function setupDesktopFindInPageBar (electronApi: IPCMainExposed): void {
226248 } ,
227249 true
228250 )
251+
252+ electronApi . onFindInPageResult ( ( result ) => {
253+ if ( ! visible ) {
254+ return
255+ }
256+ const q = getQuery ( )
257+ if ( q === '' ) {
258+ clearMatchCount ( )
259+ return
260+ }
261+ const { label, title } = describeMatchCount ( result . matches , result . activeMatchOrdinal )
262+ matchCount . textContent = label
263+ matchCount . title = title
264+ } )
229265}
230266
231267/** Left-pointing chevron; `.next::after` mirrors with `scaleX(-1)` for identical vertical alignment. */
@@ -314,6 +350,28 @@ const shadowStyles = `
314350 color: transparent;
315351}
316352
353+ .match-count {
354+ min-width: 1.5rem;
355+ padding: 0 2px;
356+ font-size: 12px;
357+ line-height: 1.35;
358+ font-variant-numeric: tabular-nums;
359+ text-align: right;
360+ color: rgba(0, 0, 0, 0.52);
361+ user-select: none;
362+ flex-shrink: 0;
363+ }
364+
365+ @media (prefers-color-scheme: dark) {
366+ .match-count {
367+ color: rgba(255, 255, 255, 0.48);
368+ }
369+ }
370+
371+ :host-context([data-theme='theme-dark']) .match-count {
372+ color: rgba(255, 255, 255, 0.48);
373+ }
374+
317375.nav {
318376 display: flex;
319377 align-items: center;
0 commit comments