|
| 1 | +// ==UserScript== |
| 2 | +// @name GitLab — commit navigation with "x" / "c" |
| 3 | +// @namespace https://github.com/solcik/userscripts |
| 4 | +// @version 0.1.0 |
| 5 | +// @description Restore the broken GitLab MR commit-by-commit shortcuts: "x" = previous commit, "c" = next commit (works around gitlab-org/gitlab#499143 on versions < 17.10). |
| 6 | +// @author David Solc |
| 7 | +// @match https://gitlab.com/*/-/merge_requests/* |
| 8 | +// @match https://git.vs-point.cz/*/-/merge_requests/* |
| 9 | +// @icon https://www.google.com/s2/favicons?sz=64&domain=gitlab.com |
| 10 | +// @homepageURL https://github.com/solcik/userscripts |
| 11 | +// @supportURL https://github.com/solcik/userscripts/issues |
| 12 | +// @updateURL https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-commit-nav.user.js |
| 13 | +// @downloadURL https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-commit-nav.user.js |
| 14 | +// @require https://cdn.jsdelivr.net/npm/mousetrap@1.6.5/mousetrap.min.js |
| 15 | +// @grant none |
| 16 | +// @license MIT |
| 17 | +// ==/UserScript== |
| 18 | + |
| 19 | +// On GitLab < 17.10 the built-in "x"/"c" commit-navigation shortcuts stopped |
| 20 | +// firing (gitlab-org/gitlab#499143), but the Prev/Next buttons GitLab renders in |
| 21 | +// single-commit MR diff view still work. Those are plain <a href> links carrying |
| 22 | +// aria-keyshortcuts="x" / "c". This script just clicks the right one. |
| 23 | + |
| 24 | +(function () { |
| 25 | + 'use strict'; |
| 26 | + |
| 27 | + // Find the Prev/Next commit link for a direction. Tries the most stable hook |
| 28 | + // (aria-keyshortcuts), then aria-label, then the chevron icon, so it keeps |
| 29 | + // working if one of them is renamed across GitLab versions. |
| 30 | + function navLink(direction) { |
| 31 | + const key = direction === 'next' ? 'c' : 'x'; |
| 32 | + const label = direction === 'next' ? 'Next commit' : 'Previous commit'; |
| 33 | + const icon = direction === 'next' ? 'chevron-right-icon' : 'chevron-left-icon'; |
| 34 | + const scope = document.querySelector('.commit-nav-buttons') || document; |
| 35 | + |
| 36 | + let link = |
| 37 | + scope.querySelector(`a[aria-keyshortcuts="${key}"]`) || |
| 38 | + scope.querySelector(`a[aria-label="${label}"]`); |
| 39 | + |
| 40 | + if (!link) { |
| 41 | + const svg = scope.querySelector(`[data-testid="${icon}"]`); |
| 42 | + link = svg && svg.closest('a'); |
| 43 | + } |
| 44 | + |
| 45 | + return link; |
| 46 | + } |
| 47 | + |
| 48 | + function go(direction) { |
| 49 | + const link = navLink(direction); |
| 50 | + if (!link) return; // not in single-commit view, or no neighbour that way |
| 51 | + if (link.classList.contains('disabled') || link.getAttribute('aria-disabled') === 'true') |
| 52 | + return; |
| 53 | + link.click(); |
| 54 | + } |
| 55 | + |
| 56 | + Mousetrap.bind('x', () => go('previous')); |
| 57 | + Mousetrap.bind('c', () => go('next')); |
| 58 | +})(); |
0 commit comments