Greasy Fork is available in English.
可自定义配置的GitHub加速下载脚本
当前为
// ==UserScript== // @name GitHub加速下载 // @namespace https://github.com/laboratorys/github-fast // @version 1.0.0 // @author Libs // @description 可自定义配置的GitHub加速下载脚本 // @license MIT License // @icon https://github.githubassets.com/favicon.ico // @include *://github.com/* // @include *://github* // @require https://scriptcat.org/lib/513/2.0.1/ElementGetter.js#sha256=V0EUYIfbOrr63nT8+W7BP1xEmWcumTLWu2PXFJHh5dg= // @require data:application/javascript,window.elmGetter%3DelmGetter // @require https://registry.npmmirror.com/vue/3.5.13/files/dist/vue.global.prod.js // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B // @require https://registry.npmmirror.com/jquery/3.7.1/files // @require https://unpkg.com/[email protected]/dist/index.prod.js // @require https://registry.npmmirror.com/pinia/2.3.0/files/dist/pinia.iife.prod.js // @grant GM.notification // @grant GM.registerMenuCommand // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function (vue, pinia$1, naiveUi, $) { "use strict"; const useStore = pinia$1.defineStore("main", { state: () => ({ showConfig: false, }), }); const _hoisted_1 = { class: "centered-content" }; const _hoisted_2 = { style: { display: "flex", "align-items": "center", width: "100%" }, }; const _sfc_main$1 = { __name: "GitHub", setup(__props) { const store = useStore(); const proxyUrlList = vue.ref([]); const projectFileDownloadUrl = vue.ref(null); const bypassDownload = vue.ref(false); const clone = vue.ref(true); const depth = vue.ref(false); const projectFileUrlList = vue.computed(() => { var hasVal = false; proxyUrlList.value.find(function (value) { if (value.url == projectFileDownloadUrl.value && value.isCheck) { hasVal = true; } }); if (!hasVal) { projectFileDownloadUrl.value = null; } return proxyUrlList.value.map((u) => ({ label: u.url, value: u.url, disabled: !u.isCheck, })); }); const onCreate = () => { return { isCheck: true, name: "", url: "", }; }; const handleUpdateCloneValue = (value) => { if (!value) { depth.value = false; } }; const handleUpdateDepthValue = (value) => { if (value) { clone.value = true; } }; const saveConfig = () => { GM_setValue("githubFastConfig", { projectFileDownloadUrl: projectFileDownloadUrl.value, proxyUrlList: proxyUrlList.value, bypassDownload: bypassDownload.value, clone: clone.value, depth: depth.value, }); GM.notification("配置更新成功,请刷新页面!"); }; const initData = () => { const config = GM_getValue("githubFastConfig"); if (config) { projectFileDownloadUrl.value = config.projectFileDownloadUrl; proxyUrlList.value = config.proxyUrlList; bypassDownload.value = config.bypassDownload; clone.value = config.clone; depth.value = config.depth; } }; initData(); return (_ctx, _cache) => { return ( vue.openBlock(), vue.createBlock( vue.unref(naiveUi.NDrawer), { show: vue.unref(store).showConfig, "onUpdate:show": _cache[6] || (_cache[6] = ($event) => (vue.unref(store).showConfig = $event)), width: 502, }, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NDrawerContent), { title: "GitHub加速配置", closable: "", }, { default: vue.withCtx(() => [ vue.createElementVNode("div", _hoisted_1, [ vue.createVNode( vue.unref(naiveUi.NForm), { "label-placement": "left", "label-width": "auto", }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(naiveUi.NH3), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NText), { type: "primary" }, { default: vue.withCtx( () => _cache[7] || (_cache[7] = [ vue.createTextVNode(" 负载均衡 "), ]) ), _: 1, } ), ]), _: 1, }), vue.createVNode( vue.unref(naiveUi.NFormItem), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NSwitch), { value: bypassDownload.value, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => (bypassDownload.value = $event)), size: "large", round: false, }, { checked: vue.withCtx( () => _cache[8] || (_cache[8] = [ vue.createTextVNode(" 开启 "), ]) ), unchecked: vue.withCtx( () => _cache[9] || (_cache[9] = [ vue.createTextVNode(" 关闭 "), ]) ), _: 1, }, 8, ["value"] ), ]), _: 1, } ), vue.createVNode(vue.unref(naiveUi.NH3), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NText), { type: "primary" }, { default: vue.withCtx( () => _cache[10] || (_cache[10] = [ vue.createTextVNode(" 克隆 "), ]) ), _: 1, } ), ]), _: 1, }), vue.createVNode( vue.unref(naiveUi.NFormItem), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NSpace), { "item-style": "display: flex;" }, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NCheckbox), { size: "large", checked: clone.value, "onUpdate:checked": [ _cache[1] || (_cache[1] = ($event) => (clone.value = $event)), handleUpdateCloneValue, ], label: "git clone", }, null, 8, ["checked"] ), vue.createVNode( vue.unref(naiveUi.NCheckbox), { size: "large", checked: depth.value, "onUpdate:checked": [ _cache[2] || (_cache[2] = ($event) => (depth.value = $event)), handleUpdateDepthValue, ], label: "--depth=1", }, null, 8, ["checked"] ), ]), _: 1, } ), ]), _: 1, } ), vue.createVNode(vue.unref(naiveUi.NH3), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NText), { type: "primary" }, { default: vue.withCtx( () => _cache[11] || (_cache[11] = [ vue.createTextVNode( " 列表文件加速 " ), ]) ), _: 1, } ), ]), _: 1, }), vue.createVNode( vue.unref(naiveUi.NFormItem), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NSelect), { value: projectFileDownloadUrl.value, "onUpdate:value": _cache[3] || (_cache[3] = ($event) => (projectFileDownloadUrl.value = $event)), options: projectFileUrlList.value, placeholder: "选择加速地址", }, null, 8, ["value", "options"] ), ]), _: 1, } ), vue.createVNode(vue.unref(naiveUi.NH3), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NText), { type: "primary" }, { default: vue.withCtx( () => _cache[12] || (_cache[12] = [ vue.createTextVNode(" 加速列表 "), ]) ), _: 1, } ), ]), _: 1, }), vue.createVNode( vue.unref(naiveUi.NFormItem), null, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NDynamicInput), { value: proxyUrlList.value, "onUpdate:value": _cache[4] || (_cache[4] = ($event) => (proxyUrlList.value = $event)), "show-sort-button": "", "on-create": onCreate, }, { "create-button-default": vue.withCtx( () => _cache[13] || (_cache[13] = [ vue.createTextVNode(" 添加 "), ]) ), default: vue.withCtx(({ value }) => [ vue.createElementVNode( "div", _hoisted_2, [ vue.createVNode( vue.unref(naiveUi.NCheckbox), { checked: value.isCheck, "onUpdate:checked": ( $event ) => (value.isCheck = $event), style: { "margin-right": "12px", }, }, null, 8, ["checked", "onUpdate:checked"] ), vue.createVNode( vue.unref(naiveUi.NInput), { class: "mr-2", value: value.name, "onUpdate:value": ($event) => (value.name = $event), type: "text", placeholder: "名称", style: { width: "40%" }, }, null, 8, ["value", "onUpdate:value"] ), vue.createVNode( vue.unref(naiveUi.NInput), { value: value.url, "onUpdate:value": ($event) => (value.url = $event), type: "text", placeholder: "加速地址", }, null, 8, ["value", "onUpdate:value"] ), ] ), ]), _: 1, }, 8, ["value"] ), ]), _: 1, } ), vue.createVNode( vue.unref(naiveUi.NSpace), { justify: "center" }, { default: vue.withCtx(() => [ vue.createVNode( vue.unref(naiveUi.NButton), { type: "primary", size: "medium", strong: "", onClick: saveConfig, }, { default: vue.withCtx( () => _cache[14] || (_cache[14] = [ vue.createTextVNode(" 保存配置 "), ]) ), _: 1, } ), vue.createVNode( vue.unref(naiveUi.NButton), { type: "default", size: "medium", strong: "", onClick: _cache[5] || (_cache[5] = ($event) => (vue.unref( store ).showConfig = false)), }, { default: vue.withCtx( () => _cache[15] || (_cache[15] = [ vue.createTextVNode(" 关闭 "), ]) ), _: 1, } ), ]), _: 1, } ), ]), _: 1, } ), ]), ]), _: 1, } ), ]), _: 1, }, 8, ["show"] ) ); }; }, }; const colorMode = vue.ref( document.querySelector("html").getAttribute("data-color-mode") ); const currentTheme = vue.ref(naiveUi.lightTheme); const updateThemeMode = () => { currentTheme.value = mql.matches ? naiveUi.darkTheme : naiveUi.lightTheme; }; const mql = window.matchMedia("(prefers-color-scheme: dark)"); mql.addEventListener("change", updateThemeMode); const initThemeMode = (mode) => { if (mode === "dark") { currentTheme.value = naiveUi.darkTheme; } else if (mode === "auto") { updateThemeMode(); } else { currentTheme.value = naiveUi.lightTheme; } }; initThemeMode(colorMode.value); new MutationObserver((mutationsList) => { for (let mutation of mutationsList) { if ( mutation.type === "attributes" && mutation.attributeName === "data-color-mode" ) { colorMode.value = document .querySelector("html") .getAttribute("data-color-mode"); initThemeMode(colorMode.value); } } }).observe(document.querySelector("html"), { attributes: true }); const _sfc_main = { __name: "App", setup(__props) { return (_ctx, _cache) => { return ( vue.openBlock(), vue.createBlock( vue.unref(naiveUi.NConfigProvider), { theme: vue.unref(currentTheme) }, { default: vue.withCtx(() => [vue.createVNode(_sfc_main$1)]), _: 1, }, 8, ["theme"] ) ); }; }, }; function run(elmGetter) { const config = GM_getValue("githubFastConfig"); const store = useStore(); GM.registerMenuCommand("加速配置", () => { store.showConfig = true; }); var MirrorUrl = pollingUrl(); if (MirrorUrl.length == 0) { return; } function setListDownBtn(elmGetter2) { elmGetter2 .get("table[aria-labelledby='folders-and-files']") .then((table) => { $(table) .find("tr") .each(function (index, item) { var rowType = $(item) .find("td:eq(1)") .find("div[class='react-directory-filename-column']") .find("svg") .attr("class"); if (rowType && rowType === "color-fg-muted") { addListDownBtn($(item)); } }); }); } function setRawBtn() { if (window.location.pathname.split("/")[3] == "blob") { addRawBtn(); } } function setReleaseBtn() { if (window.location.pathname.split("/")[3] == "releases") { addReleaseList($('div[class="Box Box--condensed mt-3"]')); } } setListDownBtn(elmGetter); setRawBtn(); setReleaseBtn(); function callback(mutations, _observer) { mutations.forEach((mutation) => { if (mutation.type == "childList" && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach((node) => { try { if ( node.className != void 0 && node.className && node.className.includes("react-directory-commit-age") ) { setListDownBtn(elmGetter); } } catch (exceptionVar) {} }); } if ( mutation.target && mutation.target.tagName === "BUTTON" && mutation.target.getAttribute("class").includes("TabNav-item") && mutation.target.getAttribute("aria-selected") === "true" && $(mutation.target).find("span").find("span").text() === "Local" ) { $(".fast-zip").remove(); addDownZipList(); if ( isShow($("#clone-with-https")) && $("#clone-with-https").length > 0 ) { $(".fast-clone").remove(); addCloneList(); } } if ( mutation.target && mutation.target.tagName === "DIV" && mutation.target.getAttribute("data-view-component") === "true" ) { setReleaseBtn(); } if ( mutation.target && mutation.target.tagName === "A" && mutation.target.getAttribute("data-testid") === "raw-button" ) { setRawBtn(); } }); } function isShow(target) { if (target.is(":visible")) { return true; } else { return false; } } const observer = new MutationObserver(callback); observer.observe(document.querySelector("body"), { attributes: true, childList: true, subtree: true, }); function addCloneList() { var href = window.location.href.split("/"); var git = href[3] + "/" + href[4] + ".git"; let inputGit = $("#__primerPortalRoot__").find("input").parent(); var InputDivClass = inputGit.attr("class"); inputGit.parent().find("span:last").attr("class"); var info = ` <span class="fast-clone" style="color:palegreen">加速列表</span>`; MirrorUrl.forEach((u) => { var Url = u.url + "/https://github.com/" + git; if (config && config.clone) { if (config.depth) { Url = "git clone --depth=1 " + Url; } else { Url = "git clone " + Url; } } info += cloneHtml(InputDivClass, Url); }); function cloneHtml(InputDivClass2, Url) { return ` <div class="${InputDivClass2} fast-clone mr-2"> <input type="text" class="form-control input-monospace input-sm color-bg-subtle" data-autoselect="true" aria-label="${Url}" readonly="" value="${Url}" tabindex="0" style="flex-grow: 1" /> <clipboard-copy value="${Url}" aria-label="Copy url to clipboard" class="ml-1 mr-0 js-clipboard-copy tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="n" role="button" ><svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon d-inline-block"> <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path> <path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path> </svg> <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-inline-block d-sm-none"> <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path> </svg> </clipboard-copy> </div> `; } $("#__primerPortalRoot__") .find("input") .parent() .parent() .find("p") .filter(function () { if (!$(this).attr("class")) { return false; } return $(this).attr("class").includes("text-normal"); }) .before($(info)); } function addDownZipList() { MirrorUrl.forEach((u) => { let downZipClone = $("#__primerPortalRoot__") .find("ul:last") .find("li:eq(1)") .clone(); downZipClone.addClass("fast-zip"); var zipPath = downZipClone.find("a").attr("href"); var Url = u.url + "/https://github.com/" + zipPath; var zipText = u.name; downZipClone.find("a").attr("href", Url); downZipClone.find("span:last").text(`Fast Download Zip [${zipText}]`); $("#__primerPortalRoot__").find("ul:last").append(downZipClone); }); } function addReleaseList(target) { target.find(".fast-release").remove(); let releaseLi = target.find("ul").find("li"); releaseLi.each(function () { var releasePath = $(this).find("a:eq(0)").attr("href"); var urls = new Array(); MirrorUrl.forEach((u) => { var Url = u.url + "/https://github.com" + releasePath; urls.push(Url); }); $(this).append(releaseHtml(urls)); }); function releaseHtml(urls) { var aHtml = ""; urls.forEach((u, index) => { var title = "下载"; if (urls.length > 1) { title = MirrorUrl[index].name; } aHtml += `<a href="${u}" rel="nofollow" data-turbo="false" data-view-component="true" class="Truncate ml-1"> <span data-view-component="true" class="Truncate-text text-bold">${title}</span> </a>`; }); return ` <div data-view-component="true" class="d-flex ml-md-3 fast-release"> <svg t="1668210029451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2795" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"> <path d="M508.746667 299.2L485.333333 452.373333a5.333333 5.333333 0 0 0 4 5.973334l217.386667 53.333333a5.333333 5.333333 0 0 1 2.72 8.693333l-184.906667 208.8a5.333333 5.333333 0 0 1-9.28-4.32l23.413334-153.226666a5.333333 5.333333 0 0 0-4-5.973334L317.173333 512a5.333333 5.333333 0 0 1-2.506666-8.48l184.8-208.693333a5.333333 5.333333 0 0 1 9.28 4.373333z m-329.493334 256l271.253334 66.666667a5.333333 5.333333 0 0 1 4 5.973333l-51.04 335.68a5.333333 5.333333 0 0 0 9.226666 4.32l434.773334-490.346667a5.333333 5.333333 0 0 0-2.72-8.693333l-271.253334-66.666667a5.333333 5.333333 0 0 1-4-5.973333l51.04-335.626667a5.333333 5.333333 0 0 0-9.226666-4.373333L176.533333 546.506667a5.333333 5.333333 0 0 0 2.72 8.693333z" p-id="2796" fill="#57606a"></path> </svg> ${aHtml} </div> `; } } function addRawBtn() { var rawUrl = $('a[data-testid="raw-button"]').attr("href"); if (rawUrl != void 0) { $(".fast-raw").remove(); MirrorUrl.forEach((u, index) => { var url = u.url + "/" + rawUrl; var rawCloneBtn = $('a[data-testid="raw-button"]').first().clone(); rawCloneBtn.addClass("fast-raw"); rawCloneBtn.text(u.name); rawCloneBtn.attr("href", url); $('a[data-testid="raw-button"]').eq(index).after(rawCloneBtn); }); } } function addListDownBtn(target) { target.find(".fileDownLink").remove(); var dLink = target.find('a[class="Link--primary"]').attr("href"); target .find('div[class="react-directory-filename-column"]') .find("svg:first") .after( listDownHtml( (config && config.projectFileDownloadUrl ? config.projectFileDownloadUrl : MirrorUrl[0].url) + "/https://github.com" + dLink, "main.go" ) ); function listDownHtml(Url, Name) { return `<a href="${Url}" download="${Name}" target="_blank" rel="noreferrer noopener nofollow" class="fileDownLink" title="${Url}" style='display:none'><svg t="1668210029451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2795" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"> <path d="M508.746667 299.2L485.333333 452.373333a5.333333 5.333333 0 0 0 4 5.973334l217.386667 53.333333a5.333333 5.333333 0 0 1 2.72 8.693333l-184.906667 208.8a5.333333 5.333333 0 0 1-9.28-4.32l23.413334-153.226666a5.333333 5.333333 0 0 0-4-5.973334L317.173333 512a5.333333 5.333333 0 0 1-2.506666-8.48l184.8-208.693333a5.333333 5.333333 0 0 1 9.28 4.373333z m-329.493334 256l271.253334 66.666667a5.333333 5.333333 0 0 1 4 5.973333l-51.04 335.68a5.333333 5.333333 0 0 0 9.226666 4.32l434.773334-490.346667a5.333333 5.333333 0 0 0-2.72-8.693333l-271.253334-66.666667a5.333333 5.333333 0 0 1-4-5.973333l51.04-335.626667a5.333333 5.333333 0 0 0-9.226666-4.373333L176.533333 546.506667a5.333333 5.333333 0 0 0 2.72 8.693333z" p-id="2796" fill="#57606a"></path> </svg></a>`; } target .find('div[class="react-directory-filename-column"]') .find("svg:first") .hover( function () { $(this).css("display", "none"); $(this).parent().find(".fileDownLink").css("display", "inline"); }, function () { $(this).css("display", "inline"); $(this).parent().find(".fileDownLink").css("display", "none"); } ); target.find(".fileDownLink").hover( function () { $(this).css("display", "inline"); $(this).parent().find("svg:first").css("display", "none"); }, function () { $(this).css("display", "none"); $(this).parent().find("svg:first").css("display", "inline"); } ); } function pollingUrl() { var proxyUrl = config ? config.proxyUrlList : new Array(); if (config && config.bypassDownload && proxyUrl.length > 0) { var index = GM_getValue("MirrorUrlIndex"); if ( index != null && index != void 0 && index + 1 <= proxyUrl.length - 1 ) { index = index + 1; } else { index = 0; } var newUrlArr = new Array(); newUrlArr[0] = proxyUrl[index]; GM_setValue("MirrorUrlIndex", index); return newUrlArr; } return proxyUrl; } } var _monkeyWindow = /* @__PURE__ */ (() => window)(); const pinia = pinia$1.createPinia(); const app = vue.createApp(_sfc_main); app.use(pinia); app.mount( (() => { const app2 = document.createElement("div"); document.body.append(app2); run(_monkeyWindow.elmGetter); return app2; })() ); })(Vue, Pinia, naive, jQuery);