// ==UserScript== // @name GitLab: copy commit reference // @namespace https://andrybak.dev // @license AGPL-3.0-only // @version 7 // @description Adds a "Copy commit reference" button to every commit page on GitLab. // @homepageURL https://gitlab.com/andrybak/copy-commit-reference-userscript // @supportURL https://gitlab.com/andrybak/copy-commit-reference-userscript/-/issues // @author Andrei Rybak // @match https://gitlab.com/*/-/commit/* // @match https://invent.kde.org/*/-/commit/* // @match https://gitlab.gnome.org/*/-/commit/* // @icon https://gitlab.com/assets/favicon-72a2cad5025aa931d6ea56c3201d1f18e68a8cd39788c7c80d5b2b82aa5143ef.png // @require https://cdn.jsdelivr.net/gh/rybak/userscript-libs@e86c722f2c9cc2a96298c8511028f15c45180185/waitForElement.js // @require https://cdn.jsdelivr.net/gh/rybak/copy-commit-reference-userscript@4f71749bc0d302d4ff4a414b0f4a6eddcc6a56ad/copy-commit-reference-lib.js // @grant none // @downloadURL none // ==/UserScript== /* * Copyright (C) 2023 Andrei Rybak * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ (function () { 'use strict'; /* * Implementation for GitLab. * * Example URLs for testing: * - https://gitlab.com/andrybak/resoday/-/commit/b82824ec6dc3f14c3711104bf0ffd792c86d19ba * - https://invent.kde.org/education/kturtle/-/commit/8beecff6f76a4afc74879c46517d00657d8426f9 */ class GitLab extends GitHosting { static #HEADER_SELECTOR = 'main#content-body .page-content-header > .header-main-content'; getTargetSelector() { return GitLab.#HEADER_SELECTOR; } getButtonTagName() { return 'button'; // like GitLab's "Copy commit SHA" } wrapButton(button) { const copyShaButtonIcon = document.querySelector(`${GitLab.#HEADER_SELECTOR} > button > svg[data-testid="copy-to-clipboard-icon"]`); const icon = copyShaButtonIcon.cloneNode(true); button.replaceChildren(icon); // is just icon enough? button.classList.add('btn-sm', 'btn-default', 'btn-default-tertiary', 'btn-icon', 'btn', 'btn-clipboard', 'gl-button'); button.setAttribute('data-toggle', 'tooltip'); // this is needed to have a fancy tooltip in style of other UI button.setAttribute('data-placement', 'bottom'); // this is needed so that the fancy tooltip appears below the button button.style = 'border: 1px solid darkgray;'; button.title = this.getButtonText() + " to clipboard"; return button; } getFullHash() { const copyShaButton = document.querySelector(`${GitLab.#HEADER_SELECTOR} > button`); return copyShaButton.getAttribute('data-clipboard-text'); } getDateIso(hash) { // careful not to select