// ==UserScript==
// @name Github Download
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 高速下载gihthub
// @author Joye-bot
// @license GPL-3.0 License
// @match *://github.com/*
// @match *://github*
// @icon https://github.githubassets.com/favicon.ico
// @grant none
// @downloadURL https://update.greasyfork.icu/scripts/451642/Github%20Download.user.js
// @updateURL https://update.greasyfork.icu/scripts/451642/Github%20Download.meta.js
// ==/UserScript==
(function () {
'use strict';
// Your code here...
const cloneUrl = [
["https://kgithub.com", "kGithub", "该公益加速源由 [kGithub] 提供
- 缓存: 无(时间很短)"],
["https://ghproxy.com/https://github.com", "ghproxy", "该公益加速源由 [ghproxy] 提供"],
["https://hub.njuu.cf", "njuu", "该公益加速源由 [LibraryCloud] 提供"],
["https://hub.yzuu.cf", "yzuu", "该公益加速源由 [LibraryCloud] 提供"],
];
const downloadUrl = [
// ["https://download.fastgit.org", "FastGit", "由KevinZonda推动的FastGit项目"],
["https://ghproxy.com/https://github.com", "ghproxy", "由 [ghproxy] 提供"],
// ["https://gh.gh2233.ml/https://github.com", "gh2333", "由 [@X.I.U/XIU2] 提供"],
// ["https://gh.ddlc.top/https://github.com", "ddlc", "由 [@mtr-static-official] 提供"]
// ['https://gh2.yanqishui.work/https://github.com', 'yanqishui', '由 [@HongjieCN] 提供'],
['https://ghdl.feizhuqwq.cf/https://github.com', 'feizhuqwq', '由 [feizhuqwq.com] 提供'],
// ['https://gh-proxy-misakano7545.koyeb.app/https://github.com', 'koyeb', ''],
['https://gh.flyinbug.top/gh/https://github.com', 'flyinbug', '由 [Mintimate] 提供'],
['https://github.91chi.fun/https://github.com', '91chi', ''],
];
const sshUrl = [
["git@git.zhlh6.cn:", "zhlh6", "利用ucloud提供的GlobalSSH"],
];
const svg = [
' ',
' ',
' '
];
const style = [
'padding:0 6px; margin-right: -1px; border-radius: 2px; background-color: var(--XIU2-back-Color); border-color: rgba(27, 31, 35, 0.1); font-size: 11px; color: var(--XIU2-font-Color);'
];
/**
* 添加克隆列表
*/
function addCloneList() {
if (document.querySelector('.XIU2-GC')) return;
let html = document.querySelector('[role="tabpanel"]:nth-child(2) div.input-group');
if (!html) return
let href_split = html.getElementsByTagName('input')[0].getAttribute('value').split(location.host);
let url = '';
let _html = '';
for (let i = 0; i < cloneUrl.length; i++) {
url = cloneUrl[i][0] + href_split[1]
_html +=
`
`;
}
html.insertAdjacentHTML('afterend', _html);
}
/**
* 添加ssh列表
*/
function addSSHList() {
if (document.querySelector('.XIU2-GCS')) return;
let html = document.querySelector('[role="tabpanel"]:nth-child(3) div.input-group');
if (!html) return;
let href_split = html.getElementsByTagName('input')[0].getAttribute('value').split(':');
let _html = '';
for (let i = 0; i < sshUrl.length; i++) {
_html +=
` `;
}
html.insertAdjacentHTML('afterend', _html);
}
/**
* 添加download zip
*/
function addDownloadZip() {
if (document.querySelector('.XIU2-DZ')) return;
let html = document.querySelectorAll('.Box-row.Box-row--hover-gray.p-3.mt-0')[1];
if (!html) return;
let href = html.getElementsByTagName('a')[0].href;
let url = '';
let _html = '';
for (let i = 0; i < downloadUrl.length; i++) {
url = downloadUrl[i][0] + href.split(location.host)[1];
_html +=
` ` +
` ` +
` ` +
` ` +
` ` +
`Download` +
`ZIP ${downloadUrl[i][1]}` +
` ` +
` `;
}
html.insertAdjacentHTML('afterend', _html);
}
/**
* 添加Releases列表
*/
function addReleasesList() {
let html = document.querySelectorAll('.Box-footer');
let divDisplay = 'margin-left: -90px;';
if (document.documentElement.clientWidth > 755) {
divDisplay = 'margin-top: -3px; margin-left: 15px; display: inherit;';
}
for (const current of html) {
if (current.querySelector('.XIU2-RS')) continue;
current.querySelectorAll('li.Box-row a').forEach(function (_this) {
let href = _this.href.split(location.host);
let url = '';
let _html = `
`;
for (let i = 0; i < downloadUrl.length; i++) {
url = downloadUrl[i][0] + href[1];
if (location.host !== "github.com") url = url.replace(location.host, "github.com");
_html +=
`${downloadUrl[i][1]} `;
}
_this.parentElement.nextElementSibling.insertAdjacentHTML('beforeend', _html + '');
}
);
}
}
/**
* 添加Tags列表
*/
function addTagsList() {
let html = document.querySelectorAll('.Box-row.position-relative.d-flex')
let divDisplay = 'margin-left: -90px;';
if (document.documentElement.clientWidth > 755) {
divDisplay = 'margin-top: -3px; margin-left: 15px; display: inherit;';
}
for (const current of html) {
let k = 0;
if (current.querySelector('.XIU2-TS')) return;
current.querySelectorAll('li.d-inline-block.mt-1.mr-2 a[rel="nofollow"]').forEach(function (_this) {
let href = _this.href.split(location.host);
let url = '';
let _html = `
`;
for (let i = 0; i < downloadUrl.length; i++) {
url = downloadUrl[i][0] + href[1];
if (location.host !== "github.com") url = url.replace(location.host, "github.com");
_html +=
`${downloadUrl[i][1]} `;
}
if (k == 0) {
_this.parentElement.nextElementSibling.insertAdjacentHTML('afterbegin', _html + '');
k++;
} else {
_this.parentElement.insertAdjacentHTML('beforeend', _html, '')
}
});
}
}
function run() {
addCloneList();
addSSHList();
addDownloadZip();
if (location.pathname.split("/")[3] === "releases") {
addReleasesList();
}
if (location.pathname.split("/")[3] === "tags") {
addTagsList();
}
if (window.onurlchange === undefined) {
addUrlChangeEvent();
}
window.addEventListener('urlchange', function () {
addCloneList();
addSSHList();
addDownloadZip();
if (location.pathname.split("/")[3] === "releases") {
addReleasesList();
}
if (location.pathname.split("/")[3] === "tags") {
addTagsList();
}
});
const callback = (mutationsList) => {
if (location.pathname.indexOf('/releases') === -1) return;
for (const mutation of mutationsList) {
for (const target of mutation.addedNodes) {
if (target.nodeType !== 1) return;
if (target.tagName === 'DIV' && target.dataset.viewComponent === 'true' && target.classList[0] === 'Box') {
addReleasesList();
}
}
}
};
const observe = new MutationObserver(callback);
const options = {
childList: true,
subtree: true
};
observe.observe(document, options);
}
run();
/**
* 添加url地址改变事件
*/
function addUrlChangeEvent() {
history.pushState = (f => function pushState() {
let ret = f.apply(this, arguments);
window.dispatchEvent(new Event('pushstate'));
window.dispatchEvent(new Event('urlchange'));
return ret;
})(history.pushState);
history.replaceState = (f => function replaceState() {
let ret = f.apply(this, arguments);
window.dispatchEvent(new Event('replacestate'));
window.dispatchEvent(new Event('urlchange'));
return ret;
})(history.replaceState);
window.addEventListener('popstate', () => {
window.dispatchEvent(new Event('urlchange'));
});
}
})();