您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在每个文件行的末尾添加按钮,以复制原始文件 URL 和下载文件
当前为
- // ==UserScript==
- // @name Github Copy Raw File URL and Download File
- // @name:zh-CN Github 复制原始文件 URL 与下载文件
- // @name:zh-TW Github 複製原始檔案 URL 與下載檔案
- // @name:vi Github Sao chép URL tệp gốc và tải xuống tệp
- // @name:ko Github 원본 파일 URL 복사 및 파일 다운로드
- // @name:ja Github 原始ファイル URL をコピーし、ファイルをダウンロードする
- // @name:en Github Copy Raw File URL and Download File
- // @name:de Github Rohdatei-URL kopieren und Datei herunterladen
- // @description Add buttons at the end of each file line to copy the raw file URL and download the file
- // @description:zh-CN 在每个文件行的末尾添加按钮,以复制原始文件 URL 和下载文件
- // @description:zh-TW 在每個檔案行的末尾添加按鈕,以複製原始檔案 URL 和下載檔案
- // @description:vi Thêm nút vào cuối mỗi dòng tệp để sao chép URL tệp gốc và tải xuống tệp
- // @description:ko 각 파일 행 끝에 원본 파일 URL 복사 및 파일 다운로드 버튼 추가
- // @description:ja 各ファイル行の末尾に、原始ファイルURLをコピーし、ファイルをダウンロードするボタンを追加
- // @description:en Add buttons at the end of each file line to copy the raw file URL and download the file
- // @description:de Fügen Sie Schaltflächen am Ende jeder Dateizeile hinzu, um die Rohdatei-URL zu kopieren und die Datei herunterzuladen
- // @namespace https://github.com/ChinaGodMan/UserScripts
- // @version 2.2.0.8
- // @author Kamikaze (https://github.com/Kamiikaze) ,人民的勤务员 <toniaiwanowskiskr47@gmail.com>
- // @match https://github.com/*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
- // @run-at document-ready
- // @license MIT
- // @supportURL https://github.com/ChinaGodMan/UserScripts/issues
- // @homepageURL https://github.com/ChinaGodMan/UserScripts
- // ==/UserScript==
- // Need an Interval to detect path changes on github tree one-pager
- // Define the number of seconds
- const scanInterval = 2
- const waitForFilelist = setInterval(() => {
- let fileListContainer = document.querySelector("div.Box > div.js-details-container.Details div") || document.querySelector("table")
- let fileList = []
- let isTable = false
- if (fileListContainer.tBodies) {
- fileList = fileListContainer.tBodies[0].children
- isTable = true
- } else {
- fileList = fileListContainer.children
- }
- if (fileList < 1) return
- appendButtons(fileList, isTable)
- }, scanInterval * 1000)
- function appendButtons(fileList, isTable = false) {
- let fileUrl = ""
- let rawFileUrl = ""
- for (let i = 0; i < fileList.length; i++) {
- let file = fileList[i]
- if (file.classList.contains("cp-btn-rdy")) continue
- file.classList.add("cp-btn-rdy")
- if (!isTable) {
- if (
- file.classList.contains("sr-only") ||
- file.childElementCount !== 4
- ) continue
- fileUrl = file.querySelector('div:nth-child(2) .js-navigation-open')
- .href
- } else {
- if (i === 0) continue
- if (
- file.classList.contains("sr-only")
- ) continue
- fileUrl = file.querySelector("a")
- .href
- file = file.querySelector("td:nth-child(4) > div")
- }
- //alert(fileUrl)
- // Dont add button if its a folder
- if (!fileUrl.includes("/blob/")) continue
- rawFileUrl = fileUrl.replace('/blob/', '/raw/')
- file.style = "display: flex; justify-content: flex-end;"
- file.append(creatyCopyButton(rawFileUrl))
- file.append(creatyDownButton(rawFileUrl))
- }
- };
- function creatyCopyButton(copyText) {
- const copy2clipboard = `
- <clipboard-copy aria-label="Copy" value="test value" data-view-component="true" class="" tabindex="0" role="button" title="Copy raw file url">
- <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy">
- <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
- </svg>
- </clipboard-copy>`
- const copyButton = document.createElement('div')
- copyButton.setAttribute('role', 'gridcell')
- copyButton.style = "margin-left: 10px; display: inline;"
- copyButton.innerHTML = copy2clipboard
- copyButton.children[0].value = copyText
- copyButton.children[0].style = "cursor: pointer;"
- return copyButton
- }
- function creatyDownButton(copyText) {
- const copy2clipboard = `
- <clipboard-copy aria-label="Download" value="test value" data-view-component="true" class="" tabindex="0" role="button" title="Download raw file url">
- <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-download">
- <path fill-rule="evenodd" d="M1.75 14.25A1.75 1.75 0 013.5 12.5h9a1.75 1.75 0 011.75 1.75v1.5a.75.75 0 01-.75.75H2.5a.75.75 0 01-.75-.75v-1.5zM10.75 9.25a.25.25 0 01.25.25v2.5a.25.25 0 01-.25.25H5.25a.25.25 0 01-.25-.25v-2.5a.25.25 0 01.25-.25h5.5zM8 1.75a.25.25 0 01.25.25v7.5a.25.25 0 01-.25.25H6.75a.25.25 0 01-.25-.25v-7.5a.25.25 0 01.25-.25h1.5zM10.25 5.25l1.5 1.5a.25.25 0 01.35 0l3-3a.25.25 0 00-.35-.35L11 5.25 9.25 3.5a.25.25 0 00-.35.35z"></path>
- </svg>
- </clipboard-copy>
- `
- const copyButton = document.createElement('div')
- copyButton.setAttribute('role', 'gridcell')
- copyButton.style = "margin-left: 10px; display: inline;"
- copyButton.innerHTML = copy2clipboard
- copyButton.children[0].value = copyText
- copyButton.children[0].style = "cursor: pointer;"
- copyButton.addEventListener('click', () => {
- // window.location.href = copyText;
- downloadFile(copyText, getFilenameFromUrl(copyText))
- })
- return copyButton
- }
- function downloadFile(url, filename) {
- var xhr = new XMLHttpRequest()
- xhr.open('GET', url, true)
- xhr.responseType = 'blob'
- xhr.onload = function () {
- if (xhr.status === 200) {
- var blob = xhr.response
- var objectUrl = window.URL.createObjectURL(blob)
- var a = document.createElement('a')
- a.href = objectUrl
- a.download = filename // 设置下载文件名
- document.body.appendChild(a)
- a.click()
- window.URL.revokeObjectURL(objectUrl) // 清理 object URL
- document.body.removeChild(a) // 清理 DOM
- }
- }
- xhr.send()
- }
- function getFilenameFromUrl(url) {
- if (typeof url !== 'string' || url.trim() === '') {
- logMessage('getFilenameFromUrl', 'URL无效,默认文件名download', false)
- return 'download' // 返回一个默认的文件名
- }
- var lastSlashIndex = url.lastIndexOf('/')
- if (lastSlashIndex === -1 || lastSlashIndex === url.length - 1) {
- logMessage('getFilenameFromUrl', 'URL格式无效缺少文件名,默认文件名download', false)
- return 'download' // 返回一个默认的文件名
- }
- var filenameWithExtension = url.substring(lastSlashIndex + 1)
- var decodedFilename = decodeURIComponent(filenameWithExtension)
- decodedFilename = decodedFilename.replace(/%20/g, '_') // 替换所有的 %20 为下划线
- return decodedFilename
- }