detached c8e4042

fix(web): keep keys inside open dialogs and name icon-only controls

An open dialog now takes only Escape, Enter and the keys that switch
dialogs, so tab and diff keys no longer act on the page behind it. In a
text field only cmd k opens the palette, and shift k is left alone.
Close and help buttons get accessible names, key hints inside buttons
are hidden from screen readers, the palette list drops its incomplete
listbox role, and a crumb is marked current only when it is. On narrow
screens the header keeps the logo and shows only the last crumb. A
missing UI font fails at start instead of leaving an empty preload.
commit
c8e404209ed2b94791a686a5e729c9286e7aba05
author
brice · · 2026-10-11 10:46 UTC
parent
c48540b
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
42 files · +324 -301
M cmd/ermite/testdata/web/blob-binary.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -132,7 +132,7 @@
132132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
133133 <div class="panel-head">
134134 <h2>Keyboard shortcuts</h2>
135-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
135+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
136136 <kbd>esc</kbd> close</button>
137137 </div>
138138 <dl class="keys">
@@ -229,7 +229,7 @@
229229 <div class="panel-head">
230230 <label for="refs-filter" class="sr">filter branches and tags</label>
231231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
232-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
232+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
233233 <kbd>esc</kbd>
234234 </button>
235235 </div>
@@ -270,11 +270,11 @@
270270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
271271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
272272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
273-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
273+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
274274 <kbd>esc</kbd>
275275 </button>
276276 </div>
277-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
277+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
278278 <li data-k="go home" data-cursor>
279279 <a href="/" tabindex="-1">
280280 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -132,7 +132,7 @@
132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
133 <div class="panel-head">133 <div class="panel-head">
134 <h2>Keyboard shortcuts</h2>134 <h2>Keyboard shortcuts</h2>
135-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">135+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
136 <kbd>esc</kbd> close</button>136 <kbd>esc</kbd> close</button>
137 </div>137 </div>
138 <dl class="keys">138 <dl class="keys">
@@ -229,7 +229,7 @@
229 <div class="panel-head">229 <div class="panel-head">
230 <label for="refs-filter" class="sr">filter branches and tags</label>230 <label for="refs-filter" class="sr">filter branches and tags</label>
231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
232-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">232+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
233 <kbd>esc</kbd>233 <kbd>esc</kbd>
234 </button>234 </button>
235 </div>235 </div>
@@ -270,11 +270,11 @@
270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
273-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">273+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
274 <kbd>esc</kbd>274 <kbd>esc</kbd>
275 </button>275 </button>
276 </div>276 </div>
277-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">277+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
278 <li data-k="go home" data-cursor>278 <li data-k="go home" data-cursor>
279 <a href="/" tabindex="-1">279 <a href="/" tabindex="-1">
280 <span class="lbl">home</span>280 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-code.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -202,7 +202,7 @@
202202 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
203203 <div class="panel-head">
204204 <h2>Keyboard shortcuts</h2>
205-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
205+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
206206 <kbd>esc</kbd> close</button>
207207 </div>
208208 <dl class="keys">
@@ -299,7 +299,7 @@
299299 <div class="panel-head">
300300 <label for="refs-filter" class="sr">filter branches and tags</label>
301301 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
302-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
302+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
303303 <kbd>esc</kbd>
304304 </button>
305305 </div>
@@ -340,11 +340,11 @@
340340 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
341341 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
342342 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
343-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
343+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
344344 <kbd>esc</kbd>
345345 </button>
346346 </div>
347-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
347+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
348348 <li data-k="go home" data-cursor>
349349 <a href="/" tabindex="-1">
350350 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -202,7 +202,7 @@
202 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">202 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
203 <div class="panel-head">203 <div class="panel-head">
204 <h2>Keyboard shortcuts</h2>204 <h2>Keyboard shortcuts</h2>
205-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">205+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
206 <kbd>esc</kbd> close</button>206 <kbd>esc</kbd> close</button>
207 </div>207 </div>
208 <dl class="keys">208 <dl class="keys">
@@ -299,7 +299,7 @@
299 <div class="panel-head">299 <div class="panel-head">
300 <label for="refs-filter" class="sr">filter branches and tags</label>300 <label for="refs-filter" class="sr">filter branches and tags</label>
301 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">301 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
302-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">302+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
303 <kbd>esc</kbd>303 <kbd>esc</kbd>
304 </button>304 </button>
305 </div>305 </div>
@@ -340,11 +340,11 @@
340 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;340 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
341 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }341 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
342 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">342 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
343-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">343+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
344 <kbd>esc</kbd>344 <kbd>esc</kbd>
345 </button>345 </button>
346 </div>346 </div>
347-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">347+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
348 <li data-k="go home" data-cursor>348 <li data-k="go home" data-cursor>
349 <a href="/" tabindex="-1">349 <a href="/" tabindex="-1">
350 <span class="lbl">home</span>350 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-empty.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -132,7 +132,7 @@
132132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
133133 <div class="panel-head">
134134 <h2>Keyboard shortcuts</h2>
135-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
135+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
136136 <kbd>esc</kbd> close</button>
137137 </div>
138138 <dl class="keys">
@@ -229,7 +229,7 @@
229229 <div class="panel-head">
230230 <label for="refs-filter" class="sr">filter branches and tags</label>
231231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
232-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
232+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
233233 <kbd>esc</kbd>
234234 </button>
235235 </div>
@@ -270,11 +270,11 @@
270270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
271271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
272272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
273-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
273+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
274274 <kbd>esc</kbd>
275275 </button>
276276 </div>
277-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
277+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
278278 <li data-k="go home" data-cursor>
279279 <a href="/" tabindex="-1">
280280 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -132,7 +132,7 @@
132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
133 <div class="panel-head">133 <div class="panel-head">
134 <h2>Keyboard shortcuts</h2>134 <h2>Keyboard shortcuts</h2>
135-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">135+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
136 <kbd>esc</kbd> close</button>136 <kbd>esc</kbd> close</button>
137 </div>137 </div>
138 <dl class="keys">138 <dl class="keys">
@@ -229,7 +229,7 @@
229 <div class="panel-head">229 <div class="panel-head">
230 <label for="refs-filter" class="sr">filter branches and tags</label>230 <label for="refs-filter" class="sr">filter branches and tags</label>
231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
232-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">232+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
233 <kbd>esc</kbd>233 <kbd>esc</kbd>
234 </button>234 </button>
235 </div>235 </div>
@@ -270,11 +270,11 @@
270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
273-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">273+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
274 <kbd>esc</kbd>274 <kbd>esc</kbd>
275 </button>275 </button>
276 </div>276 </div>
277-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">277+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
278 <li data-k="go home" data-cursor>278 <li data-k="go home" data-cursor>
279 <a href="/" tabindex="-1">279 <a href="/" tabindex="-1">
280 <span class="lbl">home</span>280 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-image.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -134,7 +134,7 @@
134134 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
135135 <div class="panel-head">
136136 <h2>Keyboard shortcuts</h2>
137-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
137+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
138138 <kbd>esc</kbd> close</button>
139139 </div>
140140 <dl class="keys">
@@ -231,7 +231,7 @@
231231 <div class="panel-head">
232232 <label for="refs-filter" class="sr">filter branches and tags</label>
233233 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
234-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
234+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
235235 <kbd>esc</kbd>
236236 </button>
237237 </div>
@@ -272,11 +272,11 @@
272272 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
273273 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
274274 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
275-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
275+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
276276 <kbd>esc</kbd>
277277 </button>
278278 </div>
279-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
279+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
280280 <li data-k="go home" data-cursor>
281281 <a href="/" tabindex="-1">
282282 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -134,7 +134,7 @@
134 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">134 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
135 <div class="panel-head">135 <div class="panel-head">
136 <h2>Keyboard shortcuts</h2>136 <h2>Keyboard shortcuts</h2>
137-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">137+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
138 <kbd>esc</kbd> close</button>138 <kbd>esc</kbd> close</button>
139 </div>139 </div>
140 <dl class="keys">140 <dl class="keys">
@@ -231,7 +231,7 @@
231 <div class="panel-head">231 <div class="panel-head">
232 <label for="refs-filter" class="sr">filter branches and tags</label>232 <label for="refs-filter" class="sr">filter branches and tags</label>
233 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">233 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
234-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">234+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
235 <kbd>esc</kbd>235 <kbd>esc</kbd>
236 </button>236 </button>
237 </div>237 </div>
@@ -272,11 +272,11 @@
272 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;272 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
273 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }273 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
274 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">274 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
275-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">275+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
276 <kbd>esc</kbd>276 <kbd>esc</kbd>
277 </button>277 </button>
278 </div>278 </div>
279-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">279+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
280 <li data-k="go home" data-cursor>280 <li data-k="go home" data-cursor>
281 <a href="/" tabindex="-1">281 <a href="/" tabindex="-1">
282 <span class="lbl">home</span>282 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-markdown.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -56,9 +56,9 @@
5656 <span class="ico i-search" aria-hidden="true">
5757 </span>
5858 <span class="search-label">Go to…</span>
59-<kbd>ctrl k</kbd>
59+<kbd aria-hidden="true">ctrl k</kbd>
6060 </button>
61-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
61+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
6262 </div>
6363 </div>
6464 <nav class="tabs" aria-label="Sections">
@@ -199,7 +199,7 @@
199199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
200200 <div class="panel-head">
201201 <h2>Keyboard shortcuts</h2>
202-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
202+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
203203 <kbd>esc</kbd> close</button>
204204 </div>
205205 <dl class="keys">
@@ -296,7 +296,7 @@
296296 <div class="panel-head">
297297 <label for="refs-filter" class="sr">filter branches and tags</label>
298298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
299-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
299+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
300300 <kbd>esc</kbd>
301301 </button>
302302 </div>
@@ -337,11 +337,11 @@
337337 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
338338 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
339339 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
340-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
340+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
341341 <kbd>esc</kbd>
342342 </button>
343343 </div>
344-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
344+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
345345 <li data-k="go home" data-cursor>
346346 <a href="/" tabindex="-1">
347347 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -56,9 +56,9 @@
56 <span class="ico i-search" aria-hidden="true">56 <span class="ico i-search" aria-hidden="true">
57 </span>57 </span>
58 <span class="search-label">Go to…</span>58 <span class="search-label">Go to…</span>
59-<kbd>ctrl k</kbd>59+<kbd aria-hidden="true">ctrl k</kbd>
60 </button>60 </button>
61-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>61+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
62 </div>62 </div>
63 </div>63 </div>
64 <nav class="tabs" aria-label="Sections">64 <nav class="tabs" aria-label="Sections">
@@ -199,7 +199,7 @@
199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
200 <div class="panel-head">200 <div class="panel-head">
201 <h2>Keyboard shortcuts</h2>201 <h2>Keyboard shortcuts</h2>
202-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">202+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
203 <kbd>esc</kbd> close</button>203 <kbd>esc</kbd> close</button>
204 </div>204 </div>
205 <dl class="keys">205 <dl class="keys">
@@ -296,7 +296,7 @@
296 <div class="panel-head">296 <div class="panel-head">
297 <label for="refs-filter" class="sr">filter branches and tags</label>297 <label for="refs-filter" class="sr">filter branches and tags</label>
298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
299-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">299+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
300 <kbd>esc</kbd>300 <kbd>esc</kbd>
301 </button>301 </button>
302 </div>302 </div>
@@ -337,11 +337,11 @@
337 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;337 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
338 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }338 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
339 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">339 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
340-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">340+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
341 <kbd>esc</kbd>341 <kbd>esc</kbd>
342 </button>342 </button>
343 </div>343 </div>
344-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">344+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
345 <li data-k="go home" data-cursor>345 <li data-k="go home" data-cursor>
346 <a href="/" tabindex="-1">346 <a href="/" tabindex="-1">
347 <span class="lbl">home</span>347 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-svg.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -157,7 +157,7 @@
157157 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
158158 <div class="panel-head">
159159 <h2>Keyboard shortcuts</h2>
160-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
160+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
161161 <kbd>esc</kbd> close</button>
162162 </div>
163163 <dl class="keys">
@@ -254,7 +254,7 @@
254254 <div class="panel-head">
255255 <label for="refs-filter" class="sr">filter branches and tags</label>
256256 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
257-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
257+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
258258 <kbd>esc</kbd>
259259 </button>
260260 </div>
@@ -295,11 +295,11 @@
295295 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
296296 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
297297 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
298-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
298+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
299299 <kbd>esc</kbd>
300300 </button>
301301 </div>
302-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
302+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
303303 <li data-k="go home" data-cursor>
304304 <a href="/" tabindex="-1">
305305 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -157,7 +157,7 @@
157 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">157 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
158 <div class="panel-head">158 <div class="panel-head">
159 <h2>Keyboard shortcuts</h2>159 <h2>Keyboard shortcuts</h2>
160-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">160+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
161 <kbd>esc</kbd> close</button>161 <kbd>esc</kbd> close</button>
162 </div>162 </div>
163 <dl class="keys">163 <dl class="keys">
@@ -254,7 +254,7 @@
254 <div class="panel-head">254 <div class="panel-head">
255 <label for="refs-filter" class="sr">filter branches and tags</label>255 <label for="refs-filter" class="sr">filter branches and tags</label>
256 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">256 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
257-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">257+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
258 <kbd>esc</kbd>258 <kbd>esc</kbd>
259 </button>259 </button>
260 </div>260 </div>
@@ -295,11 +295,11 @@
295 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;295 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
296 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }296 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
297 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">297 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
298-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">298+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
299 <kbd>esc</kbd>299 <kbd>esc</kbd>
300 </button>300 </button>
301 </div>301 </div>
302-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">302+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
303 <li data-k="go home" data-cursor>303 <li data-k="go home" data-cursor>
304 <a href="/" tabindex="-1">304 <a href="/" tabindex="-1">
305 <span class="lbl">home</span>305 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-text.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -152,7 +152,7 @@
152152 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
153153 <div class="panel-head">
154154 <h2>Keyboard shortcuts</h2>
155-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
155+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
156156 <kbd>esc</kbd> close</button>
157157 </div>
158158 <dl class="keys">
@@ -249,7 +249,7 @@
249249 <div class="panel-head">
250250 <label for="refs-filter" class="sr">filter branches and tags</label>
251251 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
252-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
252+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
253253 <kbd>esc</kbd>
254254 </button>
255255 </div>
@@ -290,11 +290,11 @@
290290 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
291291 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
292292 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
293-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
293+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
294294 <kbd>esc</kbd>
295295 </button>
296296 </div>
297-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
297+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
298298 <li data-k="go home" data-cursor>
299299 <a href="/" tabindex="-1">
300300 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -152,7 +152,7 @@
152 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">152 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
153 <div class="panel-head">153 <div class="panel-head">
154 <h2>Keyboard shortcuts</h2>154 <h2>Keyboard shortcuts</h2>
155-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">155+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
156 <kbd>esc</kbd> close</button>156 <kbd>esc</kbd> close</button>
157 </div>157 </div>
158 <dl class="keys">158 <dl class="keys">
@@ -249,7 +249,7 @@
249 <div class="panel-head">249 <div class="panel-head">
250 <label for="refs-filter" class="sr">filter branches and tags</label>250 <label for="refs-filter" class="sr">filter branches and tags</label>
251 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">251 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
252-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">252+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
253 <kbd>esc</kbd>253 <kbd>esc</kbd>
254 </button>254 </button>
255 </div>255 </div>
@@ -290,11 +290,11 @@
290 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;290 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
291 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }291 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
292 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">292 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
293-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">293+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
294 <kbd>esc</kbd>294 <kbd>esc</kbd>
295 </button>295 </button>
296 </div>296 </div>
297-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">297+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
298 <li data-k="go home" data-cursor>298 <li data-k="go home" data-cursor>
299 <a href="/" tabindex="-1">299 <a href="/" tabindex="-1">
300 <span class="lbl">home</span>300 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-too-large.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -132,7 +132,7 @@
132132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
133133 <div class="panel-head">
134134 <h2>Keyboard shortcuts</h2>
135-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
135+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
136136 <kbd>esc</kbd> close</button>
137137 </div>
138138 <dl class="keys">
@@ -229,7 +229,7 @@
229229 <div class="panel-head">
230230 <label for="refs-filter" class="sr">filter branches and tags</label>
231231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
232-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
232+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
233233 <kbd>esc</kbd>
234234 </button>
235235 </div>
@@ -270,11 +270,11 @@
270270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
271271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
272272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
273-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
273+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
274274 <kbd>esc</kbd>
275275 </button>
276276 </div>
277-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
277+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
278278 <li data-k="go home" data-cursor>
279279 <a href="/" tabindex="-1">
280280 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -132,7 +132,7 @@
132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">132 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
133 <div class="panel-head">133 <div class="panel-head">
134 <h2>Keyboard shortcuts</h2>134 <h2>Keyboard shortcuts</h2>
135-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">135+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
136 <kbd>esc</kbd> close</button>136 <kbd>esc</kbd> close</button>
137 </div>137 </div>
138 <dl class="keys">138 <dl class="keys">
@@ -229,7 +229,7 @@
229 <div class="panel-head">229 <div class="panel-head">
230 <label for="refs-filter" class="sr">filter branches and tags</label>230 <label for="refs-filter" class="sr">filter branches and tags</label>
231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">231 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
232-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">232+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
233 <kbd>esc</kbd>233 <kbd>esc</kbd>
234 </button>234 </button>
235 </div>235 </div>
@@ -270,11 +270,11 @@
270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;270 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }271 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">272 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
273-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">273+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
274 <kbd>esc</kbd>274 <kbd>esc</kbd>
275 </button>275 </button>
276 </div>276 </div>
277-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">277+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
278 <li data-k="go home" data-cursor>278 <li data-k="go home" data-cursor>
279 <a href="/" tabindex="-1">279 <a href="/" tabindex="-1">
280 <span class="lbl">home</span>280 <span class="lbl">home</span>
M cmd/ermite/testdata/web/blob-trojan.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -199,7 +199,7 @@
199199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
200200 <div class="panel-head">
201201 <h2>Keyboard shortcuts</h2>
202-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
202+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
203203 <kbd>esc</kbd> close</button>
204204 </div>
205205 <dl class="keys">
@@ -296,7 +296,7 @@
296296 <div class="panel-head">
297297 <label for="refs-filter" class="sr">filter branches and tags</label>
298298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
299-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
299+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
300300 <kbd>esc</kbd>
301301 </button>
302302 </div>
@@ -337,11 +337,11 @@
337337 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
338338 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
339339 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
340-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
340+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
341341 <kbd>esc</kbd>
342342 </button>
343343 </div>
344-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
344+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
345345 <li data-k="go home" data-cursor>
346346 <a href="/" tabindex="-1">
347347 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -199,7 +199,7 @@
199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
200 <div class="panel-head">200 <div class="panel-head">
201 <h2>Keyboard shortcuts</h2>201 <h2>Keyboard shortcuts</h2>
202-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">202+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
203 <kbd>esc</kbd> close</button>203 <kbd>esc</kbd> close</button>
204 </div>204 </div>
205 <dl class="keys">205 <dl class="keys">
@@ -296,7 +296,7 @@
296 <div class="panel-head">296 <div class="panel-head">
297 <label for="refs-filter" class="sr">filter branches and tags</label>297 <label for="refs-filter" class="sr">filter branches and tags</label>
298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
299-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">299+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
300 <kbd>esc</kbd>300 <kbd>esc</kbd>
301 </button>301 </button>
302 </div>302 </div>
@@ -337,11 +337,11 @@
337 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;337 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
338 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }338 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
339 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">339 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
340-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">340+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
341 <kbd>esc</kbd>341 <kbd>esc</kbd>
342 </button>342 </button>
343 </div>343 </div>
344-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">344+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
345 <li data-k="go home" data-cursor>345 <li data-k="go home" data-cursor>
346 <a href="/" tabindex="-1">346 <a href="/" tabindex="-1">
347 <span class="lbl">home</span>347 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-big.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -105,11 +105,11 @@
105105 </span>
106106 <span class="grow">
107107 </span>
108-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
108+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
109109 </a>
110-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
110+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
111111 </a>
112-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
112+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
113113 </button>
114114 </div>
115115 <p class="notice">this diff is incomplete: 1 file is too large to show. the totals above count everything; clone the repository to read the rest.</p>
@@ -167,7 +167,7 @@
167167 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
168168 <div class="panel-head">
169169 <h2>Keyboard shortcuts</h2>
170-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
170+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
171171 <kbd>esc</kbd> close</button>
172172 </div>
173173 <dl class="keys">
@@ -264,7 +264,7 @@
264264 <div class="panel-head">
265265 <label for="refs-filter" class="sr">filter branches and tags</label>
266266 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
267-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
267+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
268268 <kbd>esc</kbd>
269269 </button>
270270 </div>
@@ -305,11 +305,11 @@
305305 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
306306 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
307307 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
308-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
308+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
309309 <kbd>esc</kbd>
310310 </button>
311311 </div>
312-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
312+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
313313 <li data-k="go home" data-cursor>
314314 <a href="/" tabindex="-1">
315315 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -105,11 +105,11 @@
105 </span>105 </span>
106 <span class="grow">106 <span class="grow">
107 </span>107 </span>
108-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>108+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
109 </a>109 </a>
110-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>110+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
111 </a>111 </a>
112-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>112+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
113 </button>113 </button>
114 </div>114 </div>
115 <p class="notice">this diff is incomplete: 1 file is too large to show. the totals above count everything; clone the repository to read the rest.</p>115 <p class="notice">this diff is incomplete: 1 file is too large to show. the totals above count everything; clone the repository to read the rest.</p>
@@ -167,7 +167,7 @@
167 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">167 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
168 <div class="panel-head">168 <div class="panel-head">
169 <h2>Keyboard shortcuts</h2>169 <h2>Keyboard shortcuts</h2>
170-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">170+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
171 <kbd>esc</kbd> close</button>171 <kbd>esc</kbd> close</button>
172 </div>172 </div>
173 <dl class="keys">173 <dl class="keys">
@@ -264,7 +264,7 @@
264 <div class="panel-head">264 <div class="panel-head">
265 <label for="refs-filter" class="sr">filter branches and tags</label>265 <label for="refs-filter" class="sr">filter branches and tags</label>
266 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">266 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
267-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">267+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
268 <kbd>esc</kbd>268 <kbd>esc</kbd>
269 </button>269 </button>
270 </div>270 </div>
@@ -305,11 +305,11 @@
305 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;305 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
306 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }306 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
307 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">307 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
308-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">308+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
309 <kbd>esc</kbd>309 <kbd>esc</kbd>
310 </button>310 </button>
311 </div>311 </div>
312-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">312+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
313 <li data-k="go home" data-cursor>313 <li data-k="go home" data-cursor>
314 <a href="/" tabindex="-1">314 <a href="/" tabindex="-1">
315 <span class="lbl">home</span>315 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-binary.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -101,11 +101,11 @@
101101 </span>
102102 <span class="grow">
103103 </span>
104-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
104+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
105105 </a>
106-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
106+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
107107 </a>
108-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
108+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
109109 </button>
110110 </div>
111111 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -162,7 +162,7 @@
162162 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
163163 <div class="panel-head">
164164 <h2>Keyboard shortcuts</h2>
165-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
165+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
166166 <kbd>esc</kbd> close</button>
167167 </div>
168168 <dl class="keys">
@@ -259,7 +259,7 @@
259259 <div class="panel-head">
260260 <label for="refs-filter" class="sr">filter branches and tags</label>
261261 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
262-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
262+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
263263 <kbd>esc</kbd>
264264 </button>
265265 </div>
@@ -300,11 +300,11 @@
300300 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
301301 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
302302 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
303-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
303+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
304304 <kbd>esc</kbd>
305305 </button>
306306 </div>
307-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
307+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
308308 <li data-k="go home" data-cursor>
309309 <a href="/" tabindex="-1">
310310 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -101,11 +101,11 @@
101 </span>101 </span>
102 <span class="grow">102 <span class="grow">
103 </span>103 </span>
104-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>104+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
105 </a>105 </a>
106-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>106+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
107 </a>107 </a>
108-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>108+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
109 </button>109 </button>
110 </div>110 </div>
111 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">111 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -162,7 +162,7 @@
162 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">162 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
163 <div class="panel-head">163 <div class="panel-head">
164 <h2>Keyboard shortcuts</h2>164 <h2>Keyboard shortcuts</h2>
165-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">165+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
166 <kbd>esc</kbd> close</button>166 <kbd>esc</kbd> close</button>
167 </div>167 </div>
168 <dl class="keys">168 <dl class="keys">
@@ -259,7 +259,7 @@
259 <div class="panel-head">259 <div class="panel-head">
260 <label for="refs-filter" class="sr">filter branches and tags</label>260 <label for="refs-filter" class="sr">filter branches and tags</label>
261 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">261 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
262-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">262+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
263 <kbd>esc</kbd>263 <kbd>esc</kbd>
264 </button>264 </button>
265 </div>265 </div>
@@ -300,11 +300,11 @@
300 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;300 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
301 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }301 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
302 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">302 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
303-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">303+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
304 <kbd>esc</kbd>304 <kbd>esc</kbd>
305 </button>305 </button>
306 </div>306 </div>
307-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">307+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
308 <li data-k="go home" data-cursor>308 <li data-k="go home" data-cursor>
309 <a href="/" tabindex="-1">309 <a href="/" tabindex="-1">
310 <span class="lbl">home</span>310 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-merge.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -100,11 +100,11 @@
100100 </span>
101101 <span class="grow">
102102 </span>
103-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
103+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
104104 </a>
105-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
105+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
106106 </a>
107-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
107+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
108108 </button>
109109 </div>
110110 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -193,7 +193,7 @@
193193 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
194194 <div class="panel-head">
195195 <h2>Keyboard shortcuts</h2>
196-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
196+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
197197 <kbd>esc</kbd> close</button>
198198 </div>
199199 <dl class="keys">
@@ -290,7 +290,7 @@
290290 <div class="panel-head">
291291 <label for="refs-filter" class="sr">filter branches and tags</label>
292292 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
293-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
293+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
294294 <kbd>esc</kbd>
295295 </button>
296296 </div>
@@ -331,11 +331,11 @@
331331 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
332332 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
333333 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
334-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
334+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
335335 <kbd>esc</kbd>
336336 </button>
337337 </div>
338-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
338+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
339339 <li data-k="go home" data-cursor>
340340 <a href="/" tabindex="-1">
341341 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -100,11 +100,11 @@
100 </span>100 </span>
101 <span class="grow">101 <span class="grow">
102 </span>102 </span>
103-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>103+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
104 </a>104 </a>
105-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>105+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
106 </a>106 </a>
107-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>107+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
108 </button>108 </button>
109 </div>109 </div>
110 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">110 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -193,7 +193,7 @@
193 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">193 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
194 <div class="panel-head">194 <div class="panel-head">
195 <h2>Keyboard shortcuts</h2>195 <h2>Keyboard shortcuts</h2>
196-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">196+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
197 <kbd>esc</kbd> close</button>197 <kbd>esc</kbd> close</button>
198 </div>198 </div>
199 <dl class="keys">199 <dl class="keys">
@@ -290,7 +290,7 @@
290 <div class="panel-head">290 <div class="panel-head">
291 <label for="refs-filter" class="sr">filter branches and tags</label>291 <label for="refs-filter" class="sr">filter branches and tags</label>
292 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">292 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
293-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">293+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
294 <kbd>esc</kbd>294 <kbd>esc</kbd>
295 </button>295 </button>
296 </div>296 </div>
@@ -331,11 +331,11 @@
331 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;331 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
332 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }332 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
333 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">333 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
334-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">334+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
335 <kbd>esc</kbd>335 <kbd>esc</kbd>
336 </button>336 </button>
337 </div>337 </div>
338-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">338+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
339 <li data-k="go home" data-cursor>339 <li data-k="go home" data-cursor>
340 <a href="/" tabindex="-1">340 <a href="/" tabindex="-1">
341 <span class="lbl">home</span>341 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-modify-split.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -107,11 +107,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
107107 </span>
108108 <span class="grow">
109109 </span>
110-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
110+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
111111 </a>
112-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
112+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
113113 </a>
114-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
114+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
115115 </button>
116116 </div>
117117 <div id="diffs" data-diff="split">
@@ -314,7 +314,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
314314 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
315315 <div class="panel-head">
316316 <h2>Keyboard shortcuts</h2>
317-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
317+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
318318 <kbd>esc</kbd> close</button>
319319 </div>
320320 <dl class="keys">
@@ -411,7 +411,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
411411 <div class="panel-head">
412412 <label for="refs-filter" class="sr">filter branches and tags</label>
413413 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
414-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
414+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
415415 <kbd>esc</kbd>
416416 </button>
417417 </div>
@@ -452,11 +452,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
452452 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
453453 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
454454 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
455-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
455+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
456456 <kbd>esc</kbd>
457457 </button>
458458 </div>
459-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
459+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
460460 <li data-k="go home" data-cursor>
461461 <a href="/" tabindex="-1">
462462 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -107,11 +107,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
107 </span>107 </span>
108 <span class="grow">108 <span class="grow">
109 </span>109 </span>
110-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>110+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
111 </a>111 </a>
112-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>112+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
113 </a>113 </a>
114-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>114+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
115 </button>115 </button>
116 </div>116 </div>
117 <div id="diffs" data-diff="split">117 <div id="diffs" data-diff="split">
@@ -314,7 +314,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
314 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">314 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
315 <div class="panel-head">315 <div class="panel-head">
316 <h2>Keyboard shortcuts</h2>316 <h2>Keyboard shortcuts</h2>
317-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">317+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
318 <kbd>esc</kbd> close</button>318 <kbd>esc</kbd> close</button>
319 </div>319 </div>
320 <dl class="keys">320 <dl class="keys">
@@ -411,7 +411,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
411 <div class="panel-head">411 <div class="panel-head">
412 <label for="refs-filter" class="sr">filter branches and tags</label>412 <label for="refs-filter" class="sr">filter branches and tags</label>
413 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">413 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
414-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">414+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
415 <kbd>esc</kbd>415 <kbd>esc</kbd>
416 </button>416 </button>
417 </div>417 </div>
@@ -452,11 +452,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
452 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;452 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
453 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }453 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
454 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">454 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
455-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">455+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
456 <kbd>esc</kbd>456 <kbd>esc</kbd>
457 </button>457 </button>
458 </div>458 </div>
459-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">459+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
460 <li data-k="go home" data-cursor>460 <li data-k="go home" data-cursor>
461 <a href="/" tabindex="-1">461 <a href="/" tabindex="-1">
462 <span class="lbl">home</span>462 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-modify.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -107,11 +107,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
107107 </span>
108108 <span class="grow">
109109 </span>
110-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
110+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
111111 </a>
112-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
112+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
113113 </a>
114-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
114+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
115115 </button>
116116 </div>
117117 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -314,7 +314,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
314314 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
315315 <div class="panel-head">
316316 <h2>Keyboard shortcuts</h2>
317-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
317+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
318318 <kbd>esc</kbd> close</button>
319319 </div>
320320 <dl class="keys">
@@ -411,7 +411,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
411411 <div class="panel-head">
412412 <label for="refs-filter" class="sr">filter branches and tags</label>
413413 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
414-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
414+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
415415 <kbd>esc</kbd>
416416 </button>
417417 </div>
@@ -452,11 +452,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
452452 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
453453 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
454454 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
455-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
455+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
456456 <kbd>esc</kbd>
457457 </button>
458458 </div>
459-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
459+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
460460 <li data-k="go home" data-cursor>
461461 <a href="/" tabindex="-1">
462462 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -107,11 +107,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
107 </span>107 </span>
108 <span class="grow">108 <span class="grow">
109 </span>109 </span>
110-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>110+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
111 </a>111 </a>
112-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>112+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
113 </a>113 </a>
114-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>114+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
115 </button>115 </button>
116 </div>116 </div>
117 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">117 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -314,7 +314,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
314 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">314 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
315 <div class="panel-head">315 <div class="panel-head">
316 <h2>Keyboard shortcuts</h2>316 <h2>Keyboard shortcuts</h2>
317-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">317+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
318 <kbd>esc</kbd> close</button>318 <kbd>esc</kbd> close</button>
319 </div>319 </div>
320 <dl class="keys">320 <dl class="keys">
@@ -411,7 +411,7 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
411 <div class="panel-head">411 <div class="panel-head">
412 <label for="refs-filter" class="sr">filter branches and tags</label>412 <label for="refs-filter" class="sr">filter branches and tags</label>
413 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">413 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
414-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">414+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
415 <kbd>esc</kbd>415 <kbd>esc</kbd>
416 </button>416 </button>
417 </div>417 </div>
@@ -452,11 +452,11 @@ And &lt;b&gt;html&lt;/b&gt; &amp; &#34;quotes&#34;.</pre>
452 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;452 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
453 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }453 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
454 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">454 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
455-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">455+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
456 <kbd>esc</kbd>456 <kbd>esc</kbd>
457 </button>457 </button>
458 </div>458 </div>
459-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">459+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
460 <li data-k="go home" data-cursor>460 <li data-k="go home" data-cursor>
461 <a href="/" tabindex="-1">461 <a href="/" tabindex="-1">
462 <span class="lbl">home</span>462 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-rename.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -101,11 +101,11 @@
101101 </span>
102102 <span class="grow">
103103 </span>
104-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
104+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
105105 </a>
106-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
106+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
107107 </a>
108-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
108+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
109109 </button>
110110 </div>
111111 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -219,7 +219,7 @@
219219 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
220220 <div class="panel-head">
221221 <h2>Keyboard shortcuts</h2>
222-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
222+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
223223 <kbd>esc</kbd> close</button>
224224 </div>
225225 <dl class="keys">
@@ -316,7 +316,7 @@
316316 <div class="panel-head">
317317 <label for="refs-filter" class="sr">filter branches and tags</label>
318318 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
319-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
319+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
320320 <kbd>esc</kbd>
321321 </button>
322322 </div>
@@ -357,11 +357,11 @@
357357 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
358358 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
359359 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
360-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
360+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
361361 <kbd>esc</kbd>
362362 </button>
363363 </div>
364-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
364+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
365365 <li data-k="go home" data-cursor>
366366 <a href="/" tabindex="-1">
367367 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -101,11 +101,11 @@
101 </span>101 </span>
102 <span class="grow">102 <span class="grow">
103 </span>103 </span>
104-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>104+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
105 </a>105 </a>
106-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>106+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
107 </a>107 </a>
108-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>108+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
109 </button>109 </button>
110 </div>110 </div>
111 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">111 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -219,7 +219,7 @@
219 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">219 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
220 <div class="panel-head">220 <div class="panel-head">
221 <h2>Keyboard shortcuts</h2>221 <h2>Keyboard shortcuts</h2>
222-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">222+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
223 <kbd>esc</kbd> close</button>223 <kbd>esc</kbd> close</button>
224 </div>224 </div>
225 <dl class="keys">225 <dl class="keys">
@@ -316,7 +316,7 @@
316 <div class="panel-head">316 <div class="panel-head">
317 <label for="refs-filter" class="sr">filter branches and tags</label>317 <label for="refs-filter" class="sr">filter branches and tags</label>
318 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">318 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
319-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">319+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
320 <kbd>esc</kbd>320 <kbd>esc</kbd>
321 </button>321 </button>
322 </div>322 </div>
@@ -357,11 +357,11 @@
357 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;357 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
358 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }358 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
359 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">359 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
360-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">360+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
361 <kbd>esc</kbd>361 <kbd>esc</kbd>
362 </button>362 </button>
363 </div>363 </div>
364-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">364+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
365 <li data-k="go home" data-cursor>365 <li data-k="go home" data-cursor>
366 <a href="/" tabindex="-1">366 <a href="/" tabindex="-1">
367 <span class="lbl">home</span>367 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-root.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -99,11 +99,11 @@
9999 </span>
100100 <span class="grow">
101101 </span>
102-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
102+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
103103 </a>
104-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
104+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
105105 </a>
106-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
106+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
107107 </button>
108108 </div>
109109 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -511,7 +511,7 @@
511511 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
512512 <div class="panel-head">
513513 <h2>Keyboard shortcuts</h2>
514-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
514+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
515515 <kbd>esc</kbd> close</button>
516516 </div>
517517 <dl class="keys">
@@ -608,7 +608,7 @@
608608 <div class="panel-head">
609609 <label for="refs-filter" class="sr">filter branches and tags</label>
610610 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
611-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
611+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
612612 <kbd>esc</kbd>
613613 </button>
614614 </div>
@@ -649,11 +649,11 @@
649649 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
650650 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
651651 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
652-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
652+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
653653 <kbd>esc</kbd>
654654 </button>
655655 </div>
656-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
656+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
657657 <li data-k="go home" data-cursor>
658658 <a href="/" tabindex="-1">
659659 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -99,11 +99,11 @@
99 </span>99 </span>
100 <span class="grow">100 <span class="grow">
101 </span>101 </span>
102-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>102+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
103 </a>103 </a>
104-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>104+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
105 </a>105 </a>
106-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>106+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
107 </button>107 </button>
108 </div>108 </div>
109 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">109 <div id="diffs" data-diff="unified" hx-live="this.dataset.diff = sessionStorage.getItem('diff') || this.dataset.diff">
@@ -511,7 +511,7 @@
511 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">511 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
512 <div class="panel-head">512 <div class="panel-head">
513 <h2>Keyboard shortcuts</h2>513 <h2>Keyboard shortcuts</h2>
514-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">514+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
515 <kbd>esc</kbd> close</button>515 <kbd>esc</kbd> close</button>
516 </div>516 </div>
517 <dl class="keys">517 <dl class="keys">
@@ -608,7 +608,7 @@
608 <div class="panel-head">608 <div class="panel-head">
609 <label for="refs-filter" class="sr">filter branches and tags</label>609 <label for="refs-filter" class="sr">filter branches and tags</label>
610 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">610 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
611-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">611+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
612 <kbd>esc</kbd>612 <kbd>esc</kbd>
613 </button>613 </button>
614 </div>614 </div>
@@ -649,11 +649,11 @@
649 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;649 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
650 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }650 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
651 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">651 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
652-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">652+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
653 <kbd>esc</kbd>653 <kbd>esc</kbd>
654 </button>654 </button>
655 </div>655 </div>
656-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">656+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
657 <li data-k="go home" data-cursor>657 <li data-k="go home" data-cursor>
658 <a href="/" tabindex="-1">658 <a href="/" tabindex="-1">
659 <span class="lbl">home</span>659 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commit-trojan.html +10 -10
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -102,11 +102,11 @@
102102 </span>
103103 <span class="grow">
104104 </span>
105-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>
105+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
106106 </a>
107-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>
107+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
108108 </a>
109-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>
109+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
110110 </button>
111111 </div>
112112 <p class="notice">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.</p>
@@ -328,7 +328,7 @@
328328 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
329329 <div class="panel-head">
330330 <h2>Keyboard shortcuts</h2>
331-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
331+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
332332 <kbd>esc</kbd> close</button>
333333 </div>
334334 <dl class="keys">
@@ -425,7 +425,7 @@
425425 <div class="panel-head">
426426 <label for="refs-filter" class="sr">filter branches and tags</label>
427427 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
428-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
428+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
429429 <kbd>esc</kbd>
430430 </button>
431431 </div>
@@ -466,11 +466,11 @@
466466 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
467467 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
468468 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
469-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
469+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
470470 <kbd>esc</kbd>
471471 </button>
472472 </div>
473-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
473+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
474474 <li data-k="go home" data-cursor>
475475 <a href="/" tabindex="-1">
476476 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -102,11 +102,11 @@
102 </span>102 </span>
103 <span class="grow">103 <span class="grow">
104 </span>104 </span>
105-<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd>u</kbd>105+<a href="/diffs/commit/SHA40?view=unified" class="btn vbtn" data-view="unified" aria-keyshortcuts="u" aria-current="true" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;unified&#39; ? &#39;true&#39; : false">Unified<kbd aria-hidden="true">u</kbd>
106 </a>106 </a>
107-<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd>d</kbd>107+<a href="/diffs/commit/SHA40?view=split" class="btn vbtn" data-view="split" aria-keyshortcuts="d" hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))" :aria-current="q(&#39;#diffs&#39;).attr[&#39;data-diff&#39;] === &#39;split&#39; ? &#39;true&#39; : false">Split<kbd aria-hidden="true">d</kbd>
108 </a>108 </a>
109-<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd>109+<button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd>
110 </button>110 </button>
111 </div>111 </div>
112 <p class="notice">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.</p>112 <p class="notice">this diff holds invisible characters (direction controls, zero-width characters). They are shown as <span class="inv">&lt;U+XXXX&gt;</span> markers, never applied.</p>
@@ -328,7 +328,7 @@
328 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">328 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
329 <div class="panel-head">329 <div class="panel-head">
330 <h2>Keyboard shortcuts</h2>330 <h2>Keyboard shortcuts</h2>
331-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">331+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
332 <kbd>esc</kbd> close</button>332 <kbd>esc</kbd> close</button>
333 </div>333 </div>
334 <dl class="keys">334 <dl class="keys">
@@ -425,7 +425,7 @@
425 <div class="panel-head">425 <div class="panel-head">
426 <label for="refs-filter" class="sr">filter branches and tags</label>426 <label for="refs-filter" class="sr">filter branches and tags</label>
427 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">427 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
428-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">428+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
429 <kbd>esc</kbd>429 <kbd>esc</kbd>
430 </button>430 </button>
431 </div>431 </div>
@@ -466,11 +466,11 @@
466 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;466 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
467 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }467 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
468 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">468 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
469-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">469+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
470 <kbd>esc</kbd>470 <kbd>esc</kbd>
471 </button>471 </button>
472 </div>472 </div>
473-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">473+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
474 <li data-k="go home" data-cursor>474 <li data-k="go home" data-cursor>
475 <a href="/" tabindex="-1">475 <a href="/" tabindex="-1">
476 <span class="lbl">home</span>476 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commits-page2.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -161,7 +161,7 @@
161161 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
162162 <div class="panel-head">
163163 <h2>Keyboard shortcuts</h2>
164-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
164+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
165165 <kbd>esc</kbd> close</button>
166166 </div>
167167 <dl class="keys">
@@ -258,7 +258,7 @@
258258 <div class="panel-head">
259259 <label for="refs-filter" class="sr">filter branches and tags</label>
260260 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
261-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
261+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
262262 <kbd>esc</kbd>
263263 </button>
264264 </div>
@@ -291,11 +291,11 @@
291291 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
292292 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
293293 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
294-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
294+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
295295 <kbd>esc</kbd>
296296 </button>
297297 </div>
298-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
298+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
299299 <li data-k="go home" data-cursor>
300300 <a href="/" tabindex="-1">
301301 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -161,7 +161,7 @@
161 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">161 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
162 <div class="panel-head">162 <div class="panel-head">
163 <h2>Keyboard shortcuts</h2>163 <h2>Keyboard shortcuts</h2>
164-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">164+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
165 <kbd>esc</kbd> close</button>165 <kbd>esc</kbd> close</button>
166 </div>166 </div>
167 <dl class="keys">167 <dl class="keys">
@@ -258,7 +258,7 @@
258 <div class="panel-head">258 <div class="panel-head">
259 <label for="refs-filter" class="sr">filter branches and tags</label>259 <label for="refs-filter" class="sr">filter branches and tags</label>
260 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">260 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
261-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">261+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
262 <kbd>esc</kbd>262 <kbd>esc</kbd>
263 </button>263 </button>
264 </div>264 </div>
@@ -291,11 +291,11 @@
291 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;291 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
292 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }292 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
293 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">293 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
294-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">294+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
295 <kbd>esc</kbd>295 <kbd>esc</kbd>
296 </button>296 </button>
297 </div>297 </div>
298-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">298+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
299 <li data-k="go home" data-cursor>299 <li data-k="go home" data-cursor>
300 <a href="/" tabindex="-1">300 <a href="/" tabindex="-1">
301 <span class="lbl">home</span>301 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commits-path.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -176,7 +176,7 @@
176176 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
177177 <div class="panel-head">
178178 <h2>Keyboard shortcuts</h2>
179-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
179+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
180180 <kbd>esc</kbd> close</button>
181181 </div>
182182 <dl class="keys">
@@ -273,7 +273,7 @@
273273 <div class="panel-head">
274274 <label for="refs-filter" class="sr">filter branches and tags</label>
275275 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
276-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
276+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
277277 <kbd>esc</kbd>
278278 </button>
279279 </div>
@@ -306,11 +306,11 @@
306306 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
307307 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
308308 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
309-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
309+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
310310 <kbd>esc</kbd>
311311 </button>
312312 </div>
313-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
313+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
314314 <li data-k="go home" data-cursor>
315315 <a href="/" tabindex="-1">
316316 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -176,7 +176,7 @@
176 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">176 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
177 <div class="panel-head">177 <div class="panel-head">
178 <h2>Keyboard shortcuts</h2>178 <h2>Keyboard shortcuts</h2>
179-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">179+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
180 <kbd>esc</kbd> close</button>180 <kbd>esc</kbd> close</button>
181 </div>181 </div>
182 <dl class="keys">182 <dl class="keys">
@@ -273,7 +273,7 @@
273 <div class="panel-head">273 <div class="panel-head">
274 <label for="refs-filter" class="sr">filter branches and tags</label>274 <label for="refs-filter" class="sr">filter branches and tags</label>
275 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">275 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
276-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">276+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
277 <kbd>esc</kbd>277 <kbd>esc</kbd>
278 </button>278 </button>
279 </div>279 </div>
@@ -306,11 +306,11 @@
306 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;306 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
307 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }307 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
308 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">308 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
309-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">309+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
310 <kbd>esc</kbd>310 <kbd>esc</kbd>
311 </button>311 </button>
312 </div>312 </div>
313-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">313+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
314 <li data-k="go home" data-cursor>314 <li data-k="go home" data-cursor>
315 <a href="/" tabindex="-1">315 <a href="/" tabindex="-1">
316 <span class="lbl">home</span>316 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commits-root.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -963,7 +963,7 @@
963963 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
964964 <div class="panel-head">
965965 <h2>Keyboard shortcuts</h2>
966-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
966+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
967967 <kbd>esc</kbd> close</button>
968968 </div>
969969 <dl class="keys">
@@ -1060,7 +1060,7 @@
10601060 <div class="panel-head">
10611061 <label for="refs-filter" class="sr">filter branches and tags</label>
10621062 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
1063-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
1063+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
10641064 <kbd>esc</kbd>
10651065 </button>
10661066 </div>
@@ -1093,11 +1093,11 @@
10931093 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
10941094 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
10951095 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
1096-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
1096+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
10971097 <kbd>esc</kbd>
10981098 </button>
10991099 </div>
1100-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
1100+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
11011101 <li data-k="go home" data-cursor>
11021102 <a href="/" tabindex="-1">
11031103 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -963,7 +963,7 @@
963 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">963 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
964 <div class="panel-head">964 <div class="panel-head">
965 <h2>Keyboard shortcuts</h2>965 <h2>Keyboard shortcuts</h2>
966-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">966+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
967 <kbd>esc</kbd> close</button>967 <kbd>esc</kbd> close</button>
968 </div>968 </div>
969 <dl class="keys">969 <dl class="keys">
@@ -1060,7 +1060,7 @@
1060 <div class="panel-head">1060 <div class="panel-head">
1061 <label for="refs-filter" class="sr">filter branches and tags</label>1061 <label for="refs-filter" class="sr">filter branches and tags</label>
1062 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">1062 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
1063-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">1063+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
1064 <kbd>esc</kbd>1064 <kbd>esc</kbd>
1065 </button>1065 </button>
1066 </div>1066 </div>
@@ -1093,11 +1093,11 @@
1093 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;1093 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
1094 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }1094 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
1095 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">1095 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
1096-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">1096+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
1097 <kbd>esc</kbd>1097 <kbd>esc</kbd>
1098 </button>1098 </button>
1099 </div>1099 </div>
1100-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">1100+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
1101 <li data-k="go home" data-cursor>1101 <li data-k="go home" data-cursor>
1102 <a href="/" tabindex="-1">1102 <a href="/" tabindex="-1">
1103 <span class="lbl">home</span>1103 <span class="lbl">home</span>
M cmd/ermite/testdata/web/commits-small.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -308,7 +308,7 @@
308308 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
309309 <div class="panel-head">
310310 <h2>Keyboard shortcuts</h2>
311-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
311+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
312312 <kbd>esc</kbd> close</button>
313313 </div>
314314 <dl class="keys">
@@ -405,7 +405,7 @@
405405 <div class="panel-head">
406406 <label for="refs-filter" class="sr">filter branches and tags</label>
407407 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
408-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
408+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
409409 <kbd>esc</kbd>
410410 </button>
411411 </div>
@@ -446,11 +446,11 @@
446446 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
447447 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
448448 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
449-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
449+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
450450 <kbd>esc</kbd>
451451 </button>
452452 </div>
453-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
453+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
454454 <li data-k="go home" data-cursor>
455455 <a href="/" tabindex="-1">
456456 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -308,7 +308,7 @@
308 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">308 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
309 <div class="panel-head">309 <div class="panel-head">
310 <h2>Keyboard shortcuts</h2>310 <h2>Keyboard shortcuts</h2>
311-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">311+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
312 <kbd>esc</kbd> close</button>312 <kbd>esc</kbd> close</button>
313 </div>313 </div>
314 <dl class="keys">314 <dl class="keys">
@@ -405,7 +405,7 @@
405 <div class="panel-head">405 <div class="panel-head">
406 <label for="refs-filter" class="sr">filter branches and tags</label>406 <label for="refs-filter" class="sr">filter branches and tags</label>
407 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">407 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
408-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">408+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
409 <kbd>esc</kbd>409 <kbd>esc</kbd>
410 </button>410 </button>
411 </div>411 </div>
@@ -446,11 +446,11 @@
446 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;446 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
447 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }447 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
448 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">448 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
449-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">449+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
450 <kbd>esc</kbd>450 <kbd>esc</kbd>
451 </button>451 </button>
452 </div>452 </div>
453-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">453+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
454 <li data-k="go home" data-cursor>454 <li data-k="go home" data-cursor>
455 <a href="/" tabindex="-1">455 <a href="/" tabindex="-1">
456 <span class="lbl">home</span>456 <span class="lbl">home</span>
M cmd/ermite/testdata/web/empty.html +6 -6
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -38,9 +38,9 @@
3838 <span class="ico i-search" aria-hidden="true">
3939 </span>
4040 <span class="search-label">Go to…</span>
41-<kbd>ctrl k</kbd>
41+<kbd aria-hidden="true">ctrl k</kbd>
4242 </button>
43-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
43+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
4444 </div>
4545 </div>
4646 </header>
@@ -85,7 +85,7 @@
8585 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
8686 <div class="panel-head">
8787 <h2>Keyboard shortcuts</h2>
88-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
88+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
8989 <kbd>esc</kbd> close</button>
9090 </div>
9191 <dl class="keys">
@@ -188,11 +188,11 @@
188188 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
189189 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
190190 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
191-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
191+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
192192 <kbd>esc</kbd>
193193 </button>
194194 </div>
195-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
195+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
196196 <li data-k="go home" data-cursor>
197197 <a href="/" tabindex="-1">
198198 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -38,9 +38,9 @@
38 <span class="ico i-search" aria-hidden="true">38 <span class="ico i-search" aria-hidden="true">
39 </span>39 </span>
40 <span class="search-label">Go to…</span>40 <span class="search-label">Go to…</span>
41-<kbd>ctrl k</kbd>41+<kbd aria-hidden="true">ctrl k</kbd>
42 </button>42 </button>
43-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>43+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
44 </div>44 </div>
45 </div>45 </div>
46 </header>46 </header>
@@ -85,7 +85,7 @@
85 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">85 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
86 <div class="panel-head">86 <div class="panel-head">
87 <h2>Keyboard shortcuts</h2>87 <h2>Keyboard shortcuts</h2>
88-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">88+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
89 <kbd>esc</kbd> close</button>89 <kbd>esc</kbd> close</button>
90 </div>90 </div>
91 <dl class="keys">91 <dl class="keys">
@@ -188,11 +188,11 @@
188 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;188 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
189 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }189 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
190 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">190 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
191-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">191+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
192 <kbd>esc</kbd>192 <kbd>esc</kbd>
193 </button>193 </button>
194 </div>194 </div>
195-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">195+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
196 <li data-k="go home" data-cursor>196 <li data-k="go home" data-cursor>
197 <a href="/" tabindex="-1">197 <a href="/" tabindex="-1">
198 <span class="lbl">home</span>198 <span class="lbl">home</span>
M cmd/ermite/testdata/web/home.html +6 -6
@@ -24,16 +24,16 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <div class="hdr-acts">
3030 <button type="button" class="btn search" aria-haspopup="dialog" aria-controls="panel-cmd" aria-keyshortcuts="Control+K :" title="go to a section, ref, file or repo (ctrl k or :)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-cmd'))">
3131 <span class="ico i-search" aria-hidden="true">
3232 </span>
3333 <span class="search-label">Go to…</span>
34-<kbd>ctrl k</kbd>
34+<kbd aria-hidden="true">ctrl k</kbd>
3535 </button>
36-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
36+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
3737 </div>
3838 </div>
3939 </header>
@@ -115,7 +115,7 @@
115115 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
116116 <div class="panel-head">
117117 <h2>Keyboard shortcuts</h2>
118-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
118+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
119119 <kbd>esc</kbd> close</button>
120120 </div>
121121 <dl class="keys">
@@ -218,11 +218,11 @@
218218 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
219219 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
220220 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
221-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
221+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
222222 <kbd>esc</kbd>
223223 </button>
224224 </div>
225-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
225+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
226226 <li data-k="go home" data-cursor>
227227 <a href="/" tabindex="-1">
228228 <span class="lbl">home</span>
@@ -24,16 +24,16 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <div class="hdr-acts">29 <div class="hdr-acts">
30 <button type="button" class="btn search" aria-haspopup="dialog" aria-controls="panel-cmd" aria-keyshortcuts="Control+K :" title="go to a section, ref, file or repo (ctrl k or :)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-cmd'))">30 <button type="button" class="btn search" aria-haspopup="dialog" aria-controls="panel-cmd" aria-keyshortcuts="Control+K :" title="go to a section, ref, file or repo (ctrl k or :)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-cmd'))">
31 <span class="ico i-search" aria-hidden="true">31 <span class="ico i-search" aria-hidden="true">
32 </span>32 </span>
33 <span class="search-label">Go to…</span>33 <span class="search-label">Go to…</span>
34-<kbd>ctrl k</kbd>34+<kbd aria-hidden="true">ctrl k</kbd>
35 </button>35 </button>
36-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>36+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
37 </div>37 </div>
38 </div>38 </div>
39 </header>39 </header>
@@ -115,7 +115,7 @@
115 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">115 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
116 <div class="panel-head">116 <div class="panel-head">
117 <h2>Keyboard shortcuts</h2>117 <h2>Keyboard shortcuts</h2>
118-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">118+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
119 <kbd>esc</kbd> close</button>119 <kbd>esc</kbd> close</button>
120 </div>120 </div>
121 <dl class="keys">121 <dl class="keys">
@@ -218,11 +218,11 @@
218 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;218 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
219 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }219 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
220 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">220 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
221-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">221+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
222 <kbd>esc</kbd>222 <kbd>esc</kbd>
223 </button>223 </button>
224 </div>224 </div>
225-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">225+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
226 <li data-k="go home" data-cursor>226 <li data-k="go home" data-cursor>
227 <a href="/" tabindex="-1">227 <a href="/" tabindex="-1">
228 <span class="lbl">home</span>228 <span class="lbl">home</span>
M cmd/ermite/testdata/web/not-found-page.html +6 -6
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -38,9 +38,9 @@
3838 <span class="ico i-search" aria-hidden="true">
3939 </span>
4040 <span class="search-label">Go to…</span>
41-<kbd>ctrl k</kbd>
41+<kbd aria-hidden="true">ctrl k</kbd>
4242 </button>
43-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
43+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
4444 </div>
4545 </div>
4646 </header>
@@ -74,7 +74,7 @@
7474 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
7575 <div class="panel-head">
7676 <h2>Keyboard shortcuts</h2>
77-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
77+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
7878 <kbd>esc</kbd> close</button>
7979 </div>
8080 <dl class="keys">
@@ -177,11 +177,11 @@
177177 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
178178 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
179179 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
180-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
180+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
181181 <kbd>esc</kbd>
182182 </button>
183183 </div>
184-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
184+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
185185 <li data-k="go home" data-cursor>
186186 <a href="/" tabindex="-1">
187187 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -38,9 +38,9 @@
38 <span class="ico i-search" aria-hidden="true">38 <span class="ico i-search" aria-hidden="true">
39 </span>39 </span>
40 <span class="search-label">Go to…</span>40 <span class="search-label">Go to…</span>
41-<kbd>ctrl k</kbd>41+<kbd aria-hidden="true">ctrl k</kbd>
42 </button>42 </button>
43-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>43+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
44 </div>44 </div>
45 </div>45 </div>
46 </header>46 </header>
@@ -74,7 +74,7 @@
74 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">74 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
75 <div class="panel-head">75 <div class="panel-head">
76 <h2>Keyboard shortcuts</h2>76 <h2>Keyboard shortcuts</h2>
77-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">77+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
78 <kbd>esc</kbd> close</button>78 <kbd>esc</kbd> close</button>
79 </div>79 </div>
80 <dl class="keys">80 <dl class="keys">
@@ -177,11 +177,11 @@
177 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;177 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
178 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }178 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
179 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">179 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
180-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">180+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
181 <kbd>esc</kbd>181 <kbd>esc</kbd>
182 </button>182 </button>
183 </div>183 </div>
184-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">184+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
185 <li data-k="go home" data-cursor>185 <li data-k="go home" data-cursor>
186 <a href="/" tabindex="-1">186 <a href="/" tabindex="-1">
187 <span class="lbl">home</span>187 <span class="lbl">home</span>
M cmd/ermite/testdata/web/not-found.html +6 -6
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -38,9 +38,9 @@
3838 <span class="ico i-search" aria-hidden="true">
3939 </span>
4040 <span class="search-label">Go to…</span>
41-<kbd>ctrl k</kbd>
41+<kbd aria-hidden="true">ctrl k</kbd>
4242 </button>
43-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
43+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
4444 </div>
4545 </div>
4646 </header>
@@ -74,7 +74,7 @@
7474 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
7575 <div class="panel-head">
7676 <h2>Keyboard shortcuts</h2>
77-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
77+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
7878 <kbd>esc</kbd> close</button>
7979 </div>
8080 <dl class="keys">
@@ -177,11 +177,11 @@
177177 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
178178 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
179179 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
180-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
180+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
181181 <kbd>esc</kbd>
182182 </button>
183183 </div>
184-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
184+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
185185 <li data-k="go home" data-cursor>
186186 <a href="/" tabindex="-1">
187187 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -38,9 +38,9 @@
38 <span class="ico i-search" aria-hidden="true">38 <span class="ico i-search" aria-hidden="true">
39 </span>39 </span>
40 <span class="search-label">Go to…</span>40 <span class="search-label">Go to…</span>
41-<kbd>ctrl k</kbd>41+<kbd aria-hidden="true">ctrl k</kbd>
42 </button>42 </button>
43-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>43+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
44 </div>44 </div>
45 </div>45 </div>
46 </header>46 </header>
@@ -74,7 +74,7 @@
74 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">74 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
75 <div class="panel-head">75 <div class="panel-head">
76 <h2>Keyboard shortcuts</h2>76 <h2>Keyboard shortcuts</h2>
77-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">77+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
78 <kbd>esc</kbd> close</button>78 <kbd>esc</kbd> close</button>
79 </div>79 </div>
80 <dl class="keys">80 <dl class="keys">
@@ -177,11 +177,11 @@
177 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;177 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
178 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }178 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
179 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">179 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
180-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">180+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
181 <kbd>esc</kbd>181 <kbd>esc</kbd>
182 </button>182 </button>
183 </div>183 </div>
184-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">184+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
185 <li data-k="go home" data-cursor>185 <li data-k="go home" data-cursor>
186 <a href="/" tabindex="-1">186 <a href="/" tabindex="-1">
187 <span class="lbl">home</span>187 <span class="lbl">home</span>
M cmd/ermite/testdata/web/refs.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -47,9 +47,9 @@
4747 <span class="ico i-search" aria-hidden="true">
4848 </span>
4949 <span class="search-label">Go to…</span>
50-<kbd>ctrl k</kbd>
50+<kbd aria-hidden="true">ctrl k</kbd>
5151 </button>
52-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
52+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5353 </div>
5454 </div>
5555 <nav class="tabs" aria-label="Sections">
@@ -199,7 +199,7 @@
199199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
200200 <div class="panel-head">
201201 <h2>Keyboard shortcuts</h2>
202-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
202+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
203203 <kbd>esc</kbd> close</button>
204204 </div>
205205 <dl class="keys">
@@ -296,7 +296,7 @@
296296 <div class="panel-head">
297297 <label for="refs-filter" class="sr">filter branches and tags</label>
298298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
299-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
299+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
300300 <kbd>esc</kbd>
301301 </button>
302302 </div>
@@ -341,11 +341,11 @@
341341 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
342342 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
343343 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
344-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
344+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
345345 <kbd>esc</kbd>
346346 </button>
347347 </div>
348-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
348+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
349349 <li data-k="go home" data-cursor>
350350 <a href="/" tabindex="-1">
351351 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -47,9 +47,9 @@
47 <span class="ico i-search" aria-hidden="true">47 <span class="ico i-search" aria-hidden="true">
48 </span>48 </span>
49 <span class="search-label">Go to…</span>49 <span class="search-label">Go to…</span>
50-<kbd>ctrl k</kbd>50+<kbd aria-hidden="true">ctrl k</kbd>
51 </button>51 </button>
52-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>52+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
53 </div>53 </div>
54 </div>54 </div>
55 <nav class="tabs" aria-label="Sections">55 <nav class="tabs" aria-label="Sections">
@@ -199,7 +199,7 @@
199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">199 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
200 <div class="panel-head">200 <div class="panel-head">
201 <h2>Keyboard shortcuts</h2>201 <h2>Keyboard shortcuts</h2>
202-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">202+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
203 <kbd>esc</kbd> close</button>203 <kbd>esc</kbd> close</button>
204 </div>204 </div>
205 <dl class="keys">205 <dl class="keys">
@@ -296,7 +296,7 @@
296 <div class="panel-head">296 <div class="panel-head">
297 <label for="refs-filter" class="sr">filter branches and tags</label>297 <label for="refs-filter" class="sr">filter branches and tags</label>
298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">298 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
299-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">299+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
300 <kbd>esc</kbd>300 <kbd>esc</kbd>
301 </button>301 </button>
302 </div>302 </div>
@@ -341,11 +341,11 @@
341 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;341 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
342 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }342 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
343 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">343 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
344-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">344+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
345 <kbd>esc</kbd>345 <kbd>esc</kbd>
346 </button>346 </button>
347 </div>347 </div>
348-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">348+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
349 <li data-k="go home" data-cursor>349 <li data-k="go home" data-cursor>
350 <a href="/" tabindex="-1">350 <a href="/" tabindex="-1">
351 <span class="lbl">home</span>351 <span class="lbl">home</span>
M cmd/ermite/testdata/web/summary.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -44,9 +44,9 @@
4444 <span class="ico i-search" aria-hidden="true">
4545 </span>
4646 <span class="search-label">Go to…</span>
47-<kbd>ctrl k</kbd>
47+<kbd aria-hidden="true">ctrl k</kbd>
4848 </button>
49-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
49+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5050 </div>
5151 </div>
5252 <nav class="tabs" aria-label="Sections">
@@ -204,7 +204,7 @@
204204 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
205205 <div class="panel-head">
206206 <h2>Keyboard shortcuts</h2>
207-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
207+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
208208 <kbd>esc</kbd> close</button>
209209 </div>
210210 <dl class="keys">
@@ -301,7 +301,7 @@
301301 <div class="panel-head">
302302 <label for="refs-filter" class="sr">filter branches and tags</label>
303303 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
304-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
304+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
305305 <kbd>esc</kbd>
306306 </button>
307307 </div>
@@ -346,11 +346,11 @@
346346 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
347347 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
348348 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
349-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
349+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
350350 <kbd>esc</kbd>
351351 </button>
352352 </div>
353-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
353+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
354354 <li data-k="go home" data-cursor>
355355 <a href="/" tabindex="-1">
356356 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -44,9 +44,9 @@
44 <span class="ico i-search" aria-hidden="true">44 <span class="ico i-search" aria-hidden="true">
45 </span>45 </span>
46 <span class="search-label">Go to…</span>46 <span class="search-label">Go to…</span>
47-<kbd>ctrl k</kbd>47+<kbd aria-hidden="true">ctrl k</kbd>
48 </button>48 </button>
49-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>49+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
50 </div>50 </div>
51 </div>51 </div>
52 <nav class="tabs" aria-label="Sections">52 <nav class="tabs" aria-label="Sections">
@@ -204,7 +204,7 @@
204 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">204 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
205 <div class="panel-head">205 <div class="panel-head">
206 <h2>Keyboard shortcuts</h2>206 <h2>Keyboard shortcuts</h2>
207-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">207+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
208 <kbd>esc</kbd> close</button>208 <kbd>esc</kbd> close</button>
209 </div>209 </div>
210 <dl class="keys">210 <dl class="keys">
@@ -301,7 +301,7 @@
301 <div class="panel-head">301 <div class="panel-head">
302 <label for="refs-filter" class="sr">filter branches and tags</label>302 <label for="refs-filter" class="sr">filter branches and tags</label>
303 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">303 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
304-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">304+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
305 <kbd>esc</kbd>305 <kbd>esc</kbd>
306 </button>306 </button>
307 </div>307 </div>
@@ -346,11 +346,11 @@
346 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;346 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
347 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }347 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
348 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">348 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
349-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">349+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
350 <kbd>esc</kbd>350 <kbd>esc</kbd>
351 </button>351 </button>
352 </div>352 </div>
353-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">353+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
354 <li data-k="go home" data-cursor>354 <li data-k="go home" data-cursor>
355 <a href="/" tabindex="-1">355 <a href="/" tabindex="-1">
356 <span class="lbl">home</span>356 <span class="lbl">home</span>
M cmd/ermite/testdata/web/tree-nested.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -56,9 +56,9 @@
5656 <span class="ico i-search" aria-hidden="true">
5757 </span>
5858 <span class="search-label">Go to…</span>
59-<kbd>ctrl k</kbd>
59+<kbd aria-hidden="true">ctrl k</kbd>
6060 </button>
61-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
61+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
6262 </div>
6363 </div>
6464 <nav class="tabs" aria-label="Sections">
@@ -144,7 +144,7 @@
144144 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
145145 <div class="panel-head">
146146 <h2>Keyboard shortcuts</h2>
147-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
147+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
148148 <kbd>esc</kbd> close</button>
149149 </div>
150150 <dl class="keys">
@@ -241,7 +241,7 @@
241241 <div class="panel-head">
242242 <label for="refs-filter" class="sr">filter branches and tags</label>
243243 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
244-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
244+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
245245 <kbd>esc</kbd>
246246 </button>
247247 </div>
@@ -282,11 +282,11 @@
282282 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
283283 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
284284 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
285-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
285+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
286286 <kbd>esc</kbd>
287287 </button>
288288 </div>
289-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
289+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
290290 <li data-k="go home" data-cursor>
291291 <a href="/" tabindex="-1">
292292 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -56,9 +56,9 @@
56 <span class="ico i-search" aria-hidden="true">56 <span class="ico i-search" aria-hidden="true">
57 </span>57 </span>
58 <span class="search-label">Go to…</span>58 <span class="search-label">Go to…</span>
59-<kbd>ctrl k</kbd>59+<kbd aria-hidden="true">ctrl k</kbd>
60 </button>60 </button>
61-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>61+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
62 </div>62 </div>
63 </div>63 </div>
64 <nav class="tabs" aria-label="Sections">64 <nav class="tabs" aria-label="Sections">
@@ -144,7 +144,7 @@
144 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">144 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
145 <div class="panel-head">145 <div class="panel-head">
146 <h2>Keyboard shortcuts</h2>146 <h2>Keyboard shortcuts</h2>
147-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">147+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
148 <kbd>esc</kbd> close</button>148 <kbd>esc</kbd> close</button>
149 </div>149 </div>
150 <dl class="keys">150 <dl class="keys">
@@ -241,7 +241,7 @@
241 <div class="panel-head">241 <div class="panel-head">
242 <label for="refs-filter" class="sr">filter branches and tags</label>242 <label for="refs-filter" class="sr">filter branches and tags</label>
243 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">243 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
244-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">244+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
245 <kbd>esc</kbd>245 <kbd>esc</kbd>
246 </button>246 </button>
247 </div>247 </div>
@@ -282,11 +282,11 @@
282 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;282 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
283 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }283 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
284 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">284 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
285-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">285+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
286 <kbd>esc</kbd>286 <kbd>esc</kbd>
287 </button>287 </button>
288 </div>288 </div>
289-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">289+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
290 <li data-k="go home" data-cursor>290 <li data-k="go home" data-cursor>
291 <a href="/" tabindex="-1">291 <a href="/" tabindex="-1">
292 <span class="lbl">home</span>292 <span class="lbl">home</span>
M cmd/ermite/testdata/web/tree-root.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -50,9 +50,9 @@
5050 <span class="ico i-search" aria-hidden="true">
5151 </span>
5252 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>
53+<kbd aria-hidden="true">ctrl k</kbd>
5454 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5656 </div>
5757 </div>
5858 <nav class="tabs" aria-label="Sections">
@@ -371,7 +371,7 @@
371371 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
372372 <div class="panel-head">
373373 <h2>Keyboard shortcuts</h2>
374-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
374+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
375375 <kbd>esc</kbd> close</button>
376376 </div>
377377 <dl class="keys">
@@ -468,7 +468,7 @@
468468 <div class="panel-head">
469469 <label for="refs-filter" class="sr">filter branches and tags</label>
470470 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
471-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
471+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
472472 <kbd>esc</kbd>
473473 </button>
474474 </div>
@@ -509,11 +509,11 @@
509509 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
510510 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
511511 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
512-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
512+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
513513 <kbd>esc</kbd>
514514 </button>
515515 </div>
516-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
516+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
517517 <li data-k="go home" data-cursor>
518518 <a href="/" tabindex="-1">
519519 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -50,9 +50,9 @@
50 <span class="ico i-search" aria-hidden="true">50 <span class="ico i-search" aria-hidden="true">
51 </span>51 </span>
52 <span class="search-label">Go to…</span>52 <span class="search-label">Go to…</span>
53-<kbd>ctrl k</kbd>53+<kbd aria-hidden="true">ctrl k</kbd>
54 </button>54 </button>
55-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>55+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
56 </div>56 </div>
57 </div>57 </div>
58 <nav class="tabs" aria-label="Sections">58 <nav class="tabs" aria-label="Sections">
@@ -371,7 +371,7 @@
371 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">371 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
372 <div class="panel-head">372 <div class="panel-head">
373 <h2>Keyboard shortcuts</h2>373 <h2>Keyboard shortcuts</h2>
374-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">374+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
375 <kbd>esc</kbd> close</button>375 <kbd>esc</kbd> close</button>
376 </div>376 </div>
377 <dl class="keys">377 <dl class="keys">
@@ -468,7 +468,7 @@
468 <div class="panel-head">468 <div class="panel-head">
469 <label for="refs-filter" class="sr">filter branches and tags</label>469 <label for="refs-filter" class="sr">filter branches and tags</label>
470 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">470 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
471-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">471+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
472 <kbd>esc</kbd>472 <kbd>esc</kbd>
473 </button>473 </button>
474 </div>474 </div>
@@ -509,11 +509,11 @@
509 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;509 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
510 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }510 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
511 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">511 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
512-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">512+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
513 <kbd>esc</kbd>513 <kbd>esc</kbd>
514 </button>514 </button>
515 </div>515 </div>
516-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">516+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
517 <li data-k="go home" data-cursor>517 <li data-k="go home" data-cursor>
518 <a href="/" tabindex="-1">518 <a href="/" tabindex="-1">
519 <span class="lbl">home</span>519 <span class="lbl">home</span>
M cmd/ermite/testdata/web/tree-slash-ref.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -141,7 +141,7 @@
141141 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
142142 <div class="panel-head">
143143 <h2>Keyboard shortcuts</h2>
144-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
144+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
145145 <kbd>esc</kbd> close</button>
146146 </div>
147147 <dl class="keys">
@@ -238,7 +238,7 @@
238238 <div class="panel-head">
239239 <label for="refs-filter" class="sr">filter branches and tags</label>
240240 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
241-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
241+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
242242 <kbd>esc</kbd>
243243 </button>
244244 </div>
@@ -279,11 +279,11 @@
279279 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
280280 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
281281 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
282-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
282+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
283283 <kbd>esc</kbd>
284284 </button>
285285 </div>
286-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
286+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
287287 <li data-k="go home" data-cursor>
288288 <a href="/" tabindex="-1">
289289 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -141,7 +141,7 @@
141 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">141 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
142 <div class="panel-head">142 <div class="panel-head">
143 <h2>Keyboard shortcuts</h2>143 <h2>Keyboard shortcuts</h2>
144-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">144+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
145 <kbd>esc</kbd> close</button>145 <kbd>esc</kbd> close</button>
146 </div>146 </div>
147 <dl class="keys">147 <dl class="keys">
@@ -238,7 +238,7 @@
238 <div class="panel-head">238 <div class="panel-head">
239 <label for="refs-filter" class="sr">filter branches and tags</label>239 <label for="refs-filter" class="sr">filter branches and tags</label>
240 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">240 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
241-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">241+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
242 <kbd>esc</kbd>242 <kbd>esc</kbd>
243 </button>243 </button>
244 </div>244 </div>
@@ -279,11 +279,11 @@
279 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;279 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
280 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }280 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
281 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">281 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
282-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">282+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
283 <kbd>esc</kbd>283 <kbd>esc</kbd>
284 </button>284 </button>
285 </div>285 </div>
286-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">286+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
287 <li data-k="go home" data-cursor>287 <li data-k="go home" data-cursor>
288 <a href="/" tabindex="-1">288 <a href="/" tabindex="-1">
289 <span class="lbl">home</span>289 <span class="lbl">home</span>
M cmd/ermite/testdata/web/tree-subdir.html +7 -7
@@ -24,7 +24,7 @@
2424 <a class="brand" href="/" data-g="h" title="home (g h)">
2525 <span class="brand-mark" aria-hidden="true">
2626 </span>
27-<span>example.test</span>
27+<span class="brand-name">example.test</span>
2828 </a>
2929 <nav class="crumbs" aria-label="Path">
3030 <ol>
@@ -53,9 +53,9 @@
5353 <span class="ico i-search" aria-hidden="true">
5454 </span>
5555 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>
56+<kbd aria-hidden="true">ctrl k</kbd>
5757 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
5959 </div>
6060 </div>
6161 <nav class="tabs" aria-label="Sections">
@@ -166,7 +166,7 @@
166166 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
167167 <div class="panel-head">
168168 <h2>Keyboard shortcuts</h2>
169-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
169+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
170170 <kbd>esc</kbd> close</button>
171171 </div>
172172 <dl class="keys">
@@ -263,7 +263,7 @@
263263 <div class="panel-head">
264264 <label for="refs-filter" class="sr">filter branches and tags</label>
265265 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
266-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
266+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
267267 <kbd>esc</kbd>
268268 </button>
269269 </div>
@@ -304,11 +304,11 @@
304304 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
305305 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
306306 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
307-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">
307+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
308308 <kbd>esc</kbd>
309309 </button>
310310 </div>
311-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
311+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
312312 <li data-k="go home" data-cursor>
313313 <a href="/" tabindex="-1">
314314 <span class="lbl">home</span>
@@ -24,7 +24,7 @@
24 <a class="brand" href="/" data-g="h" title="home (g h)">24 <a class="brand" href="/" data-g="h" title="home (g h)">
25 <span class="brand-mark" aria-hidden="true">25 <span class="brand-mark" aria-hidden="true">
26 </span>26 </span>
27-<span>example.test</span>27+<span class="brand-name">example.test</span>
28 </a>28 </a>
29 <nav class="crumbs" aria-label="Path">29 <nav class="crumbs" aria-label="Path">
30 <ol>30 <ol>
@@ -53,9 +53,9 @@
53 <span class="ico i-search" aria-hidden="true">53 <span class="ico i-search" aria-hidden="true">
54 </span>54 </span>
55 <span class="search-label">Go to…</span>55 <span class="search-label">Go to…</span>
56-<kbd>ctrl k</kbd>56+<kbd aria-hidden="true">ctrl k</kbd>
57 </button>57 </button>
58-<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>58+<button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
59 </div>59 </div>
60 </div>60 </div>
61 <nav class="tabs" aria-label="Sections">61 <nav class="tabs" aria-label="Sections">
@@ -166,7 +166,7 @@
166 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">166 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
167 <div class="panel-head">167 <div class="panel-head">
168 <h2>Keyboard shortcuts</h2>168 <h2>Keyboard shortcuts</h2>
169-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">169+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
170 <kbd>esc</kbd> close</button>170 <kbd>esc</kbd> close</button>
171 </div>171 </div>
172 <dl class="keys">172 <dl class="keys">
@@ -263,7 +263,7 @@
263 <div class="panel-head">263 <div class="panel-head">
264 <label for="refs-filter" class="sr">filter branches and tags</label>264 <label for="refs-filter" class="sr">filter branches and tags</label>
265 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">265 <input id="refs-filter" type="search" placeholder="Switch branch or tag…" autocomplete="off" data-pick hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))">
266-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">266+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
267 <kbd>esc</kbd>267 <kbd>esc</kbd>
268 </button>268 </button>
269 </div>269 </div>
@@ -304,11 +304,11 @@
304 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;304 let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;
305 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }305 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
306 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">306 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }">
307-<button type="button" class="panel-x" hx-on:click="closest('dialog').close()">307+<button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()">
308 <kbd>esc</kbd>308 <kbd>esc</kbd>
309 </button>309 </button>
310 </div>310 </div>
311-<ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">311+<ul id="cmd-list" class="cmd-list" aria-label="Targets">
312 <li data-k="go home" data-cursor>312 <li data-k="go home" data-cursor>
313 <a href="/" tabindex="-1">313 <a href="/" tabindex="-1">
314 <span class="lbl">home</span>314 <span class="lbl">home</span>
M internal/adapters/web/assets.go +4 -0
@@ -4,6 +4,7 @@ package web
44
55 import (
66 "crypto/sha256"
7+ "errors"
78 "embed"
89 "encoding/hex"
910 "io/fs"
@@ -107,6 +108,9 @@ func loadAssets() (*assetSet, error) {
107108 css.WriteString("/* " + path.Base(f) + " */\n")
108109 css.Write(b)
109110 }
111+ if s.urls.Font == "" {
112+ return nil, errors.New("web: the UI font static/fonts/atkinson-next.woff2 is missing")
113+ }
110114 sheet := strings.NewReplacer(refs...).Replace(css.String())
111115 s.urls.CSS = put("css", "ermite.css", []byte(sheet), "text/css; charset=utf-8")
112116
@@ -4,6 +4,7 @@ package web
4 4
5 import (5 import (
6 "crypto/sha256"6 "crypto/sha256"
7+ "errors"
7 "embed"8 "embed"
8 "encoding/hex"9 "encoding/hex"
9 "io/fs"10 "io/fs"
@@ -107,6 +108,9 @@ func loadAssets() (*assetSet, error) {
107 css.WriteString("/* " + path.Base(f) + " */\n")108 css.WriteString("/* " + path.Base(f) + " */\n")
108 css.Write(b)109 css.Write(b)
109 }110 }
111+ if s.urls.Font == "" {
112+ return nil, errors.New("web: the UI font static/fonts/atkinson-next.woff2 is missing")
113+ }
110 sheet := strings.NewReplacer(refs...).Replace(css.String())114 sheet := strings.NewReplacer(refs...).Replace(css.String())
111 s.urls.CSS = put("css", "ermite.css", []byte(sheet), "text/css; charset=utf-8")115 s.urls.CSS = put("css", "ermite.css", []byte(sheet), "text/css; charset=utf-8")
112 116
M internal/adapters/web/diff.templ +2 -2
@@ -55,7 +55,7 @@ templ Commit(l Layout, p CommitPage) {
5555 <span class="grow"></span>
5656 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)
5757 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)
58- <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd></button>
58+ <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd></button>
5959 </div>
6060 if p.Invisible {
6161 <p class="notice">
@@ -109,7 +109,7 @@ templ viewLink(p DiffView, view, label, key, href string) {
109109 hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))"
110110 :aria-current={ "q('#diffs').attr['data-diff'] === '" + view + "' ? 'true' : false" }
111111 }
112- >{ label }<kbd>{ key }</kbd></a>
112+ >{ label }<kbd aria-hidden="true">{ key }</kbd></a>
113113 }
114114
115115 templ personView(pr Person) {
@@ -55,7 +55,7 @@ templ Commit(l Layout, p CommitPage) {
55 <span class="grow"></span>55 <span class="grow"></span>
56 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)56 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)
57 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)57 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)
58- <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd></button>58+ <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd></button>
59 </div>59 </div>
60 if p.Invisible {60 if p.Invisible {
61 <p class="notice">61 <p class="notice">
@@ -109,7 +109,7 @@ templ viewLink(p DiffView, view, label, key, href string) {
109 hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))"109 hx-on:click="event.preventDefault(); document.body.dispatchEvent(new CustomEvent('k-' + this.dataset.view))"
110 :aria-current={ "q('#diffs').attr['data-diff'] === '" + view + "' ? 'true' : false" }110 :aria-current={ "q('#diffs').attr['data-diff'] === '" + view + "' ? 'true' : false" }
111 }111 }
112- >{ label }<kbd>{ key }</kbd></a>112+ >{ label }<kbd aria-hidden="true">{ key }</kbd></a>
113 }113 }
114 114
115 templ personView(pr Person) {115 templ personView(pr Person) {
M internal/adapters/web/diff_templ.go +3 -3 generated file: collapsed
M internal/adapters/web/mr.templ +2 -2
@@ -168,7 +168,7 @@ templ MergeRequest(l Layout, p MRPage) {
168168 <span class="grow"></span>
169169 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)
170170 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)
171- <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd></button>
171+ <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd></button>
172172 </div>
173173 if p.Invisible {
174174 <p class="notice">
@@ -448,7 +448,7 @@ templ Compare(l Layout, p ComparePage) {
448448 <span class="grow"></span>
449449 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)
450450 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)
451- <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd></button>
451+ <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd></button>
452452 </div>
453453 if p.Invisible {
454454 <p class="notice">
@@ -168,7 +168,7 @@ templ MergeRequest(l Layout, p MRPage) {
168 <span class="grow"></span>168 <span class="grow"></span>
169 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)169 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)
170 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)170 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)
171- <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd></button>171+ <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd></button>
172 </div>172 </div>
173 if p.Invisible {173 if p.Invisible {
174 <p class="notice">174 <p class="notice">
@@ -448,7 +448,7 @@ templ Compare(l Layout, p ComparePage) {
448 <span class="grow"></span>448 <span class="grow"></span>
449 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)449 @viewLink(p.DiffView, "unified", "Unified", "u", p.UnifiedHref)
450 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)450 @viewLink(p.DiffView, "split", "Split", "d", p.SplitHref)
451- <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd>x</kbd></button>451+ <button type="button" aria-keyshortcuts="x" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-collapse'))" class="btn">Collapse all<kbd aria-hidden="true">x</kbd></button>
452 </div>452 </div>
453 if p.Invisible {453 if p.Invisible {
454 <p class="notice">454 <p class="notice">
M internal/adapters/web/mr_templ.go +2 -2 generated file: collapsed
M internal/adapters/web/overlays.templ +4 -4
@@ -7,7 +7,7 @@ import "strings"
77 // OverlayHelp is the keyboard map panel.
88 templ OverlayHelp() {
99 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
10- <div class="panel-head"><h2>Keyboard shortcuts</h2><button type="button" class="panel-x" hx-on:click="closest('dialog').close()"><kbd>esc</kbd> close</button></div>
10+ <div class="panel-head"><h2>Keyboard shortcuts</h2><button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()"><kbd>esc</kbd> close</button></div>
1111 <dl class="keys">
1212 <div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div>
1313 <div><dt><kbd>?</kbd></dt><dd>this list</dd></div>
@@ -40,7 +40,7 @@ templ OverlayRefs(l Layout) {
4040 data-pick
4141 hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))"
4242 />
43- <button type="button" class="panel-x" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>
43+ <button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>
4444 </div>
4545 <div class="panel-cols" data-picklist>
4646 <section aria-label="Branches">
@@ -105,9 +105,9 @@ templ OverlayCmd(items []CmdItem) {
105105 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
106106 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }"
107107 />
108- <button type="button" class="panel-x" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>
108+ <button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>
109109 </div>
110- <ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">
110+ <ul id="cmd-list" class="cmd-list" aria-label="Targets">
111111 for i, c := range items {
112112 <li data-k={ strings.ToLower(c.Kind + " " + c.Label) } data-cursor?={ i == 0 }><a href={ templ.SafeURL(c.Href) } tabindex="-1"><span class="lbl">{ c.Label }</span><span class="k">{ c.Kind }</span></a></li>
113113 }
@@ -7,7 +7,7 @@ import "strings"
7 // OverlayHelp is the keyboard map panel.7 // OverlayHelp is the keyboard map panel.
8 templ OverlayHelp() {8 templ OverlayHelp() {
9 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">9 <dialog id="panel-help" class="panel modal" aria-label="Keyboard shortcuts" hx-on:keydown="event.key === 'Escape' && (event.preventDefault(), this.close())" hx-on:click="event.target === this && this.close()">
10- <div class="panel-head"><h2>Keyboard shortcuts</h2><button type="button" class="panel-x" hx-on:click="closest('dialog').close()"><kbd>esc</kbd> close</button></div>10+ <div class="panel-head"><h2>Keyboard shortcuts</h2><button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()"><kbd>esc</kbd> close</button></div>
11 <dl class="keys">11 <dl class="keys">
12 <div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div>12 <div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div>
13 <div><dt><kbd>?</kbd></dt><dd>this list</dd></div>13 <div><dt><kbd>?</kbd></dt><dd>this list</dd></div>
@@ -40,7 +40,7 @@ templ OverlayRefs(l Layout) {
40 data-pick40 data-pick
41 hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))"41 hx-on:input="let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))"
42 />42 />
43- <button type="button" class="panel-x" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>43+ <button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>
44 </div>44 </div>
45 <div class="panel-cols" data-picklist>45 <div class="panel-cols" data-picklist>
46 <section aria-label="Branches">46 <section aria-label="Branches">
@@ -105,9 +105,9 @@ templ OverlayCmd(items []CmdItem) {
105 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }105 if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }
106 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }"106 else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }"
107 />107 />
108- <button type="button" class="panel-x" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>108+ <button type="button" class="panel-x" aria-label="Close" hx-on:click="closest('dialog').close()"><kbd>esc</kbd></button>
109 </div>109 </div>
110- <ul id="cmd-list" class="cmd-list" role="listbox" aria-label="Targets">110+ <ul id="cmd-list" class="cmd-list" aria-label="Targets">
111 for i, c := range items {111 for i, c := range items {
112 <li data-k={ strings.ToLower(c.Kind + " " + c.Label) } data-cursor?={ i == 0 }><a href={ templ.SafeURL(c.Href) } tabindex="-1"><span class="lbl">{ c.Label }</span><span class="k">{ c.Kind }</span></a></li>112 <li data-k={ strings.ToLower(c.Kind + " " + c.Label) } data-cursor?={ i == 0 }><a href={ templ.SafeURL(c.Href) } tabindex="-1"><span class="lbl">{ c.Label }</span><span class="k">{ c.Kind }</span></a></li>
113 }113 }
M internal/adapters/web/overlays_templ.go +3 -3
@@ -34,7 +34,7 @@ func OverlayHelp() templ.Component {
3434 templ_7745c5c3_Var1 = templ.NopComponent
3535 }
3636 ctx = templ.ClearChildren(ctx)
37- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><h2>Keyboard shortcuts</h2><button type=\"button\" class=\"panel-x\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd> close</button></div><dl class=\"keys\"><div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div><div><dt><kbd>?</kbd></dt><dd>this list</dd></div><div><dt><kbd>j</kbd> <kbd>k</kbd></dt><dd>move the row cursor down / up</dd></div><div><dt><kbd>enter</kbd></dt><dd>open the row under the cursor</dd></div><div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div><div><dt><kbd>/</kbd></dt><dd>filter the list</dd></div><div><dt><kbd>b</kbd></dt><dd>")
37+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><h2>Keyboard shortcuts</h2><button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd> close</button></div><dl class=\"keys\"><div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div><div><dt><kbd>?</kbd></dt><dd>this list</dd></div><div><dt><kbd>j</kbd> <kbd>k</kbd></dt><dd>move the row cursor down / up</dd></div><div><dt><kbd>enter</kbd></dt><dd>open the row under the cursor</dd></div><div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div><div><dt><kbd>/</kbd></dt><dd>filter the list</dd></div><div><dt><kbd>b</kbd></dt><dd>")
3838 if templ_7745c5c3_Err != nil {
3939 return templ_7745c5c3_Err
4040 }
@@ -78,7 +78,7 @@ func OverlayRefs(l Layout) templ.Component {
7878 }
7979 ctx = templ.ClearChildren(ctx)
8080 if l.Ref != "" {
81- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"refs-filter\" class=\"sr\">filter branches and tags</label> <input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick hx-on:input=\"let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))\"> <button type=\"button\" class=\"panel-x\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><div class=\"panel-cols\" data-picklist><section aria-label=\"Branches\"><h2>Branches <span class=\"count\">")
81+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"refs-filter\" class=\"sr\">filter branches and tags</label> <input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick hx-on:input=\"let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))\"> <button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><div class=\"panel-cols\" data-picklist><section aria-label=\"Branches\"><h2>Branches <span class=\"count\">")
8282 if templ_7745c5c3_Err != nil {
8383 return templ_7745c5c3_Err
8484 }
@@ -236,7 +236,7 @@ func OverlayCmd(items []CmdItem) templ.Component {
236236 templ_7745c5c3_Var9 = templ.NopComponent
237237 }
238238 ctx = templ.ClearChildren(ctx)
239- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"cmd-q\" class=\"sr\">go to</label> <input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" aria-controls=\"cmd-list\" hx-on:input=\"let t = this.value.toLowerCase().trim();\n q('#cmd-list > li').arr().forEach(li => li.hidden = !li.dataset.k.includes(t));\n let first = q('#cmd-list > li:not([hidden])').arr()[0]; first && q(first).take('data-cursor', '#cmd-list > li')\" hx-on:keydown=\"let vis = q('#cmd-list > li:not([hidden])').arr();\n let i = vis.findIndex(li => li.hasAttribute('data-cursor'));\n let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;\n if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }\n else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }\"> <button type=\"button\" class=\"panel-x\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><ul id=\"cmd-list\" class=\"cmd-list\" role=\"listbox\" aria-label=\"Targets\">")
239+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"cmd-q\" class=\"sr\">go to</label> <input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" aria-controls=\"cmd-list\" hx-on:input=\"let t = this.value.toLowerCase().trim();\n q('#cmd-list > li').arr().forEach(li => li.hidden = !li.dataset.k.includes(t));\n let first = q('#cmd-list > li:not([hidden])').arr()[0]; first && q(first).take('data-cursor', '#cmd-list > li')\" hx-on:keydown=\"let vis = q('#cmd-list > li:not([hidden])').arr();\n let i = vis.findIndex(li => li.hasAttribute('data-cursor'));\n let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;\n if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }\n else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }\"> <button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><ul id=\"cmd-list\" class=\"cmd-list\" aria-label=\"Targets\">")
240240 if templ_7745c5c3_Err != nil {
241241 return templ_7745c5c3_Err
242242 }
@@ -34,7 +34,7 @@ func OverlayHelp() templ.Component {
34 templ_7745c5c3_Var1 = templ.NopComponent34 templ_7745c5c3_Var1 = templ.NopComponent
35 }35 }
36 ctx = templ.ClearChildren(ctx)36 ctx = templ.ClearChildren(ctx)
37- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><h2>Keyboard shortcuts</h2><button type=\"button\" class=\"panel-x\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd> close</button></div><dl class=\"keys\"><div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div><div><dt><kbd>?</kbd></dt><dd>this list</dd></div><div><dt><kbd>j</kbd> <kbd>k</kbd></dt><dd>move the row cursor down / up</dd></div><div><dt><kbd>enter</kbd></dt><dd>open the row under the cursor</dd></div><div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div><div><dt><kbd>/</kbd></dt><dd>filter the list</dd></div><div><dt><kbd>b</kbd></dt><dd>")37+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<dialog id=\"panel-help\" class=\"panel modal\" aria-label=\"Keyboard shortcuts\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><h2>Keyboard shortcuts</h2><button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd> close</button></div><dl class=\"keys\"><div><dt><kbd>ctrl k</kbd> <kbd>:</kbd></dt><dd>go to a section, branch, tag, file or repository</dd></div><div><dt><kbd>?</kbd></dt><dd>this list</dd></div><div><dt><kbd>j</kbd> <kbd>k</kbd></dt><dd>move the row cursor down / up</dd></div><div><dt><kbd>enter</kbd></dt><dd>open the row under the cursor</dd></div><div><dt><kbd>g g</kbd> <kbd>G</kbd></dt><dd>first / last row</dd></div><div><dt><kbd>/</kbd></dt><dd>filter the list</dd></div><div><dt><kbd>b</kbd></dt><dd>")
38 if templ_7745c5c3_Err != nil {38 if templ_7745c5c3_Err != nil {
39 return templ_7745c5c3_Err39 return templ_7745c5c3_Err
40 }40 }
@@ -78,7 +78,7 @@ func OverlayRefs(l Layout) templ.Component {
78 }78 }
79 ctx = templ.ClearChildren(ctx)79 ctx = templ.ClearChildren(ctx)
80 if l.Ref != "" {80 if l.Ref != "" {
81- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"refs-filter\" class=\"sr\">filter branches and tags</label> <input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick hx-on:input=\"let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))\"> <button type=\"button\" class=\"panel-x\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><div class=\"panel-cols\" data-picklist><section aria-label=\"Branches\"><h2>Branches <span class=\"count\">")81+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<dialog id=\"panel-refs\" class=\"panel modal\" aria-label=\"Switch ref\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"refs-filter\" class=\"sr\">filter branches and tags</label> <input id=\"refs-filter\" type=\"search\" placeholder=\"Switch branch or tag…\" autocomplete=\"off\" data-pick hx-on:input=\"let t = this.value.toLowerCase(); q('#panel-refs li').arr().forEach(li => li.hidden = !li.textContent.toLowerCase().includes(t))\"> <button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><div class=\"panel-cols\" data-picklist><section aria-label=\"Branches\"><h2>Branches <span class=\"count\">")
82 if templ_7745c5c3_Err != nil {82 if templ_7745c5c3_Err != nil {
83 return templ_7745c5c3_Err83 return templ_7745c5c3_Err
84 }84 }
@@ -236,7 +236,7 @@ func OverlayCmd(items []CmdItem) templ.Component {
236 templ_7745c5c3_Var9 = templ.NopComponent236 templ_7745c5c3_Var9 = templ.NopComponent
237 }237 }
238 ctx = templ.ClearChildren(ctx)238 ctx = templ.ClearChildren(ctx)
239- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"cmd-q\" class=\"sr\">go to</label> <input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" aria-controls=\"cmd-list\" hx-on:input=\"let t = this.value.toLowerCase().trim();\n q('#cmd-list > li').arr().forEach(li => li.hidden = !li.dataset.k.includes(t));\n let first = q('#cmd-list > li:not([hidden])').arr()[0]; first && q(first).take('data-cursor', '#cmd-list > li')\" hx-on:keydown=\"let vis = q('#cmd-list > li:not([hidden])').arr();\n let i = vis.findIndex(li => li.hasAttribute('data-cursor'));\n let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;\n if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }\n else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }\"> <button type=\"button\" class=\"panel-x\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><ul id=\"cmd-list\" class=\"cmd-list\" role=\"listbox\" aria-label=\"Targets\">")239+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<dialog id=\"panel-cmd\" class=\"panel modal\" aria-label=\"Go to\" hx-on:keydown=\"event.key === 'Escape' && (event.preventDefault(), this.close())\" hx-on:click=\"event.target === this && this.close()\"><div class=\"panel-head\"><label for=\"cmd-q\" class=\"sr\">go to</label> <input id=\"cmd-q\" type=\"search\" placeholder=\"Go to a section, branch, tag, file or repository…\" autocomplete=\"off\" spellcheck=\"false\" aria-controls=\"cmd-list\" hx-on:input=\"let t = this.value.toLowerCase().trim();\n q('#cmd-list > li').arr().forEach(li => li.hidden = !li.dataset.k.includes(t));\n let first = q('#cmd-list > li:not([hidden])').arr()[0]; first && q(first).take('data-cursor', '#cmd-list > li')\" hx-on:keydown=\"let vis = q('#cmd-list > li:not([hidden])').arr();\n let i = vis.findIndex(li => li.hasAttribute('data-cursor'));\n let step = event.key === 'ArrowDown' ? 1 : event.key === 'ArrowUp' ? -1 : 0;\n if (step) { event.preventDefault(); let n = vis[Math.max(0, Math.min(vis.length - 1, i + step))]; n && (q(n).take('data-cursor', '#cmd-list > li'), n.scrollIntoView({ block: 'nearest' })) }\n else if (event.key === 'Enter') { event.preventDefault(); vis[Math.max(i, 0)]?.querySelector('a').click() }\"> <button type=\"button\" class=\"panel-x\" aria-label=\"Close\" hx-on:click=\"closest('dialog').close()\"><kbd>esc</kbd></button></div><ul id=\"cmd-list\" class=\"cmd-list\" aria-label=\"Targets\">")
240 if templ_7745c5c3_Err != nil {240 if templ_7745c5c3_Err != nil {
241 return templ_7745c5c3_Err241 return templ_7745c5c3_Err
242 }242 }
M internal/adapters/web/shell.templ +8 -4
@@ -51,7 +51,7 @@ templ Header(l Layout) {
5151 <div class="hdr-top">
5252 <a class="brand" href="/" data-g="h" title="home (g h)">
5353 <span class="brand-mark" aria-hidden="true"></span>
54- <span>{ l.Instance }</span>
54+ <span class="brand-name">{ l.Instance }</span>
5555 </a>
5656 if len(l.Crumbs) > 0 {
5757 <nav class="crumbs" aria-label="Path">
@@ -66,7 +66,11 @@ templ Header(l Layout) {
6666 }
6767 >{ c.Label }</a>
6868 } else {
69- <span aria-current="page">{ c.Label }</span>
69+ <span
70+ if c.Current {
71+ aria-current="page"
72+ }
73+ >{ c.Label }</span>
7074 }
7175 </li>
7276 }
@@ -100,9 +104,9 @@ templ Header(l Layout) {
100104 >
101105 <span class="ico i-search" aria-hidden="true"></span>
102106 <span class="search-label">Go to…</span>
103- <kbd>ctrl k</kbd>
107+ <kbd aria-hidden="true">ctrl k</kbd>
104108 </button>
105- <button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
109+ <button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
106110 if SignedIn(ctx) {
107111 <form class="owner" method="post" action="/-/logout">
108112 <span class="owner-badge" title="signed in as the owner">owner</span>
@@ -51,7 +51,7 @@ templ Header(l Layout) {
51 <div class="hdr-top">51 <div class="hdr-top">
52 <a class="brand" href="/" data-g="h" title="home (g h)">52 <a class="brand" href="/" data-g="h" title="home (g h)">
53 <span class="brand-mark" aria-hidden="true"></span>53 <span class="brand-mark" aria-hidden="true"></span>
54- <span>{ l.Instance }</span>54+ <span class="brand-name">{ l.Instance }</span>
55 </a>55 </a>
56 if len(l.Crumbs) > 0 {56 if len(l.Crumbs) > 0 {
57 <nav class="crumbs" aria-label="Path">57 <nav class="crumbs" aria-label="Path">
@@ -66,7 +66,11 @@ templ Header(l Layout) {
66 }66 }
67 >{ c.Label }</a>67 >{ c.Label }</a>
68 } else {68 } else {
69- <span aria-current="page">{ c.Label }</span>69+ <span
70+ if c.Current {
71+ aria-current="page"
72+ }
73+ >{ c.Label }</span>
70 }74 }
71 </li>75 </li>
72 }76 }
@@ -100,9 +104,9 @@ templ Header(l Layout) {
100 >104 >
101 <span class="ico i-search" aria-hidden="true"></span>105 <span class="ico i-search" aria-hidden="true"></span>
102 <span class="search-label">Go to…</span>106 <span class="search-label">Go to…</span>
103- <kbd>ctrl k</kbd>107+ <kbd aria-hidden="true">ctrl k</kbd>
104 </button>108 </button>
105- <button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>109+ <button type="button" class="btn icon" aria-haspopup="dialog" aria-controls="panel-help" aria-keyshortcuts="?" aria-label="Keyboard shortcuts" title="keyboard shortcuts (?)" hx-on:click="document.body.dispatchEvent(new CustomEvent('k-help'))">?</button>
106 if SignedIn(ctx) {110 if SignedIn(ctx) {
107 <form class="owner" method="post" action="/-/logout">111 <form class="owner" method="post" action="/-/logout">
108 <span class="owner-badge" title="signed in as the owner">owner</span>112 <span class="owner-badge" title="signed in as the owner">owner</span>
M internal/adapters/web/shell_templ.go +49 -39 generated file: collapsed
M internal/adapters/web/static/css/20-shell.css +3 -2
@@ -49,7 +49,7 @@
4949 .brand {
5050 display: flex; align-items: center; gap: var(--s2); flex: none;
5151 font: 700 var(--fs) / 1 var(--mono); color: var(--ink-hi); text-decoration: none;
52- & span { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
52+ & .brand-name { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
5353 &:hover { text-decoration: none; }
5454 }
5555 .brand-mark {
@@ -174,7 +174,8 @@
174174 @media (max-width: 720px) {
175175 :root { --pad: var(--s4); }
176176 .hdr-top { gap: var(--s3); height: 52px; }
177- .brand span { display: none; }
177+ .brand-name { display: none; }
178+ .crumbs li:not(:last-child) { display: none; }
178179 .ref .sha, .owner-badge, .hdr-acts .icon { display: none; }
179180 .ref { max-width: 16ch; }
180181 .work { padding-top: var(--s4); }
@@ -49,7 +49,7 @@
49 .brand {49 .brand {
50 display: flex; align-items: center; gap: var(--s2); flex: none;50 display: flex; align-items: center; gap: var(--s2); flex: none;
51 font: 700 var(--fs) / 1 var(--mono); color: var(--ink-hi); text-decoration: none;51 font: 700 var(--fs) / 1 var(--mono); color: var(--ink-hi); text-decoration: none;
52- & span { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }52+ & .brand-name { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
53 &:hover { text-decoration: none; }53 &:hover { text-decoration: none; }
54 }54 }
55 .brand-mark {55 .brand-mark {
@@ -174,7 +174,8 @@
174 @media (max-width: 720px) {174 @media (max-width: 720px) {
175 :root { --pad: var(--s4); }175 :root { --pad: var(--s4); }
176 .hdr-top { gap: var(--s3); height: 52px; }176 .hdr-top { gap: var(--s3); height: 52px; }
177- .brand span { display: none; }177+ .brand-name { display: none; }
178+ .crumbs li:not(:last-child) { display: none; }
178 .ref .sha, .owner-badge, .hdr-acts .icon { display: none; }179 .ref .sha, .owner-badge, .hdr-acts .icon { display: none; }
179 .ref { max-width: 16ch; }180 .ref { max-width: 16ch; }
180 .work { padding-top: var(--s4); }181 .work { padding-top: var(--s4); }
M internal/adapters/web/static/js/ermite.js +7 -3
@@ -9,12 +9,16 @@
99 let pending = 0;
1010 const fire = (name) => document.body.dispatchEvent(new CustomEvent('k-' + name, { bubbles: false }));
1111 addEventListener('keydown', (e) => {
12- // ctrl k / cmd k opens the palette from anywhere, inputs included.
13- if ((e.ctrlKey || e.metaKey) && !e.altKey && e.key.toLowerCase() === 'k') { e.preventDefault(); pending = 0; return fire('cmd'); }
14- if (e.ctrlKey || e.metaKey || e.altKey) return;
1512 const typing = e.target.closest('input, textarea, select, [contenteditable]');
13+ // ctrl k / cmd k opens the palette; in a field only cmd k, so that the
14+ // field keeps ctrl k (kill to end of line on macOS).
15+ if ((e.metaKey || (e.ctrlKey && !typing)) && !e.altKey && !e.shiftKey && e.key.toLowerCase() === 'k') { e.preventDefault(); pending = 0; return fire('cmd'); }
16+ if (e.ctrlKey || e.metaKey || e.altKey) return;
1617 if (e.key === 'Escape') { pending = 0; if (typing) e.target.blur(); return fire('esc'); }
1718 if (typing) return;
19+ // An open dialog takes only the keys that move between dialogs: the page
20+ // behind it does not react (scripted clicks would go through inert).
21+ if (document.querySelector('dialog[open]') && !['?', 'b', ':', 'f', 'Enter'].includes(e.key)) { pending = 0; return; }
1822 if (e.key === 'Enter' && e.target.closest('a, button, summary')) return;
1923 if (pending) {
2024 const name = goto[e.key];
@@ -9,12 +9,16 @@
9 let pending = 0;9 let pending = 0;
10 const fire = (name) => document.body.dispatchEvent(new CustomEvent('k-' + name, { bubbles: false }));10 const fire = (name) => document.body.dispatchEvent(new CustomEvent('k-' + name, { bubbles: false }));
11 addEventListener('keydown', (e) => {11 addEventListener('keydown', (e) => {
12- // ctrl k / cmd k opens the palette from anywhere, inputs included.
13- if ((e.ctrlKey || e.metaKey) && !e.altKey && e.key.toLowerCase() === 'k') { e.preventDefault(); pending = 0; return fire('cmd'); }
14- if (e.ctrlKey || e.metaKey || e.altKey) return;
15 const typing = e.target.closest('input, textarea, select, [contenteditable]');12 const typing = e.target.closest('input, textarea, select, [contenteditable]');
13+ // ctrl k / cmd k opens the palette; in a field only cmd k, so that the
14+ // field keeps ctrl k (kill to end of line on macOS).
15+ if ((e.metaKey || (e.ctrlKey && !typing)) && !e.altKey && !e.shiftKey && e.key.toLowerCase() === 'k') { e.preventDefault(); pending = 0; return fire('cmd'); }
16+ if (e.ctrlKey || e.metaKey || e.altKey) return;
16 if (e.key === 'Escape') { pending = 0; if (typing) e.target.blur(); return fire('esc'); }17 if (e.key === 'Escape') { pending = 0; if (typing) e.target.blur(); return fire('esc'); }
17 if (typing) return;18 if (typing) return;
19+ // An open dialog takes only the keys that move between dialogs: the page
20+ // behind it does not react (scripted clicks would go through inert).
21+ if (document.querySelector('dialog[open]') && !['?', 'b', ':', 'f', 'Enter'].includes(e.key)) { pending = 0; return; }
18 if (e.key === 'Enter' && e.target.closest('a, button, summary')) return;22 if (e.key === 'Enter' && e.target.closest('a, button, summary')) return;
19 if (pending) {23 if (pending) {
20 const name = goto[e.key];24 const name = goto[e.key];

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 2

Tags 45

↑↓ moveenter openesc close