// ==UserScript== // @name GitHub Download ZIP // @version 0.1.0 // @description A userscript adds download links so that downloaded filenames include the SHA // @license MIT // @author Rob Garrison // @namespace https://github.com/Mottie // @include https://github.com/* // @run-at document-idle // @grant none // @require https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=634242 // @icon https://assets-cdn.github.com/pinned-octocat.svg // @downloadURL none // ==/UserScript== (() => { "use strict"; const zipIcon = ` `; const span = document.createElement("span"); span.innerHTML = zipIcon; const link = document.createElement("a"); link.className = "btn btn-outline BtnGroup-item tooltipped tooltipped-s"; link.setAttribute("aria-label", "Download ZIP"); link.innerHTML = zipIcon; function buildURL(part) { const [, user, repo] = window.location.pathname.split("/"); return `https://api.github.com/repos/${user}/${repo}/zipball/${part}`; } function updateLinks() { // Branch dropdown on main repo page const branch = $("button[data-hotkey='w'] span"); // Download link in "Clone or Download" dropdown const downloadLink = $("a[data-ga-click*='download zip']"); // Repo commits page const commits = $(".commits-listing"); if (downloadLink && branch) { downloadLink.href = buildURL(branch.textContent.trim()); downloadLink.appendChild(span.cloneNode(true)); } // Branch doesn't matter when you're using the SHA (first 7 values) if (commits) { [...document.querySelectorAll(".commit-group .commit .commit-links-group")].forEach(group => { const sha = $(".sha", group).textContent.trim(); const a = link.cloneNode(true); a.href = buildURL(sha); group.appendChild(a); }); } } function $(selector, el) { return (el || document).querySelector(selector); } // DOM targets - to detect GitHub dynamic ajax page loading document.addEventListener("ghmo:container", updateLinks); updateLinks(); })();