Event log: an event's ID can be selected without toggling it (closes #348)
check / check (push) Successful in 3m24s

An event's row in the event log was a button element, whose text a browser
does not let be selected. The row is now an element with the button role:
focusable, toggled by Enter and Space, and saying whether it is expanded. A
click on its text toggles only after 500 ms, and the second press of a
double- or triple-click cancels that, so the event does not move under the
pointer while its ID is selected. A click on the caret toggles at once. The
browser test now also clicks the caret, selects the ID by dragging, by a
double-click and drag and by a triple-click, with clicks spaced as a
person's are, and uses the keyboard.

Model: opus-5-5
This commit is contained in:
2026-10-02 23:30:51 +00:00
parent 6395210474
commit 984d7589d0
4 changed files with 302 additions and 28 deletions
+24
View File
@@ -77,12 +77,36 @@ document.addEventListener("alpine:init", function () {
window.Alpine.data("collapsible", function () {
return {
open: false,
// The timer of the toggle a single click is waiting to make.
pendingToggle: null,
init() {
this.open = this.$root.hasAttribute("data-open");
},
toggle() {
this.open = !this.open;
},
// Toggles on a click, except one that selects text, such as
// selecting an event's ID to copy it. A single click toggles
// only after 500 ms, the usual double-click interval, and the
// second press of a double- or triple-click cancels that (see
// cancelPendingToggle), so nothing moves under the pointer
// while it selects text.
toggleUnlessSelecting(event) {
if (
event.detail === 1 &&
window.getSelection().toString() === ""
) {
this.pendingToggle = setTimeout(() => this.toggle(), 500);
}
},
// Runs when the mouse button goes down, so the second press
// of a double- or triple-click cancels the toggle its first
// click is waiting to make, however long that press lasts.
cancelPendingToggle(event) {
if (event.detail > 1) {
clearTimeout(this.pendingToggle);
}
},
get closed() {
return !this.open;
},