(event: KeyboardEvent)
| 13 | ], comment)); |
| 14 | |
| 15 | function runShortcuts(event: KeyboardEvent): void { |
| 16 | if (!'jkx'.includes(event.key) || isEditable(event.target)) { |
| 17 | return; |
| 18 | } |
| 19 | |
| 20 | event.preventDefault(); |
| 21 | const targetElement = $optional(':target'); |
| 22 | |
| 23 | if (event.key === 'x') { |
| 24 | // The event handler is quite broad, there's no guarantee that the intention is to toggle "Viewed" |
| 25 | $optional(viewedToggleSelector, targetElement)?.click(); |
| 26 | return; |
| 27 | } |
| 28 | |
| 29 | const items = $$([ |
| 30 | 'div[class*="targetable" i][id^="diff-"]', // Files in diffs |
| 31 | '.js-minimizable-comment-group', // Comments (to be `.filter()`ed) |
| 32 | ]) |
| 33 | .filter(element => |
| 34 | element.classList.contains('js-minimizable-comment-group') |
| 35 | ? !isCommentGroupMinimized(element) |
| 36 | : true, |
| 37 | ); |
| 38 | |
| 39 | // `j` goes to the next item, `k` goes back an item |
| 40 | const direction = event.key === 'j' ? 1 : -1; |
| 41 | // Without `targetElement`, it will start from -1 |
| 42 | const currentIndex = items.indexOf(targetElement!); |
| 43 | |
| 44 | // Start at 0 if nothing is; clamp index |
| 45 | const chosenItemIndex = Math.min( |
| 46 | Math.max(0, currentIndex + direction), |
| 47 | items.length - 1, |
| 48 | ); |
| 49 | |
| 50 | if (currentIndex !== chosenItemIndex) { |
| 51 | // Make item a target without pushing to history |
| 52 | location.replace('#' + items[chosenItemIndex].id); |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | function init(signal: AbortSignal): void { |
| 57 | document.body.addEventListener('keypress', runShortcuts, {signal}); |
nothing calls this directly
no test coverage detected