On GitHub release pages, strips the "sha256:" (and other hash) prefix when copying asset checksums
// ==UserScript==
// @name GitHub Release - Strip Hash Prefix
// @namespace https://github.com/anon
// @version 1.0
// @description On GitHub release pages, strips the "sha256:" (and other hash) prefix when copying asset checksums
// @match https://github.com/*/*/releases*
// @grant none
// @license CC-BY-NC-SA-4.0
// ==/UserScript==
(function() {
'use strict';
const HASH_PREFIXES = /^(sha256|sha1|sha512|sha384|md5|sha224|sha3_256|sha3_384|sha3_512|sha3_224):/;
function stripPrefix(value) {
const match = value.match(HASH_PREFIXES);
return match ? value.slice(match[0].length) : value;
}
function wireClipboardCopy(el) {
if (el.dataset.hashStripped) return;
const origValue = el.getAttribute('value');
if (!origValue || !HASH_PREFIXES.test(origValue)) return;
el.setAttribute('value', stripPrefix(origValue));
el.dataset.hashStripped = '1';
// Update the displayed text span
const truncateText = el.closest('.Box-row')?.querySelector('.Truncate-text');
if (truncateText) {
truncateText.textContent = stripPrefix(truncateText.textContent);
}
}
function scan() {
document.querySelectorAll('clipboard-copy').forEach(wireClipboardCopy);
}
scan();
new MutationObserver(mutations => {
for (const m of mutations) {
for (const node of m.addedNodes) {
if (node.nodeType !== 1) continue;
if (node.matches && node.matches('clipboard-copy')) {
wireClipboardCopy(node);
}
if (node.querySelectorAll) {
node.querySelectorAll('clipboard-copy').forEach(wireClipboardCopy);
}
}
}
}).observe(document.documentElement, { childList: true, subtree: true });
})();