您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
To show download counter for each attachment from Releases page on GitHub.com
// ==UserScript== // @name GitHubReleasesCount // @description To show download counter for each attachment from Releases page on GitHub.com // @namespace net.r_eg.GitHubReleasesCount // @version 0.4 // @grant none // @include https://github.com/*/*/releases* // @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js // @author https://github.com/3F // @license MIT // ==/UserScript== /* Here's sandbox as the main page of this script at this time: - https://github.com/3F/sandbox/tree/master/javascript/_user_scripts/GitHubReleasesCount Tested via: - Firefox 61.0.2 + Greasemonkey 4.6 - Firefox 59.0.2 + Greasemonkey 4.3 - Firefox 55.0.3 & 54.0.1 + Greasemonkey 3.11 Changes: * 0.4: Fixed the work with modern GitHub Releases ~ Aug 2018 * 0.3: Fixed the work with modern GitHub Releases ~(Jan 2018 - Apr 2018) * 0.2: individual tags & multi-pages support (+async). * 0.1: first idea. */ (function() { 'use strict'; class GhrCounter extends function(){ this.constructor.prototype.$ = { /** assets from the releases page */ pageFiles: ".release-header + :first-of-type li a", /** 'user/project' from url */ usrprj: /^\/([^/]+)\/([^/]+)/g, apiserver: 'api.github.com', out: { class: 'Label Label--outline Label--outline-green text-gray', style: 'margin-right: 3px;', }, debug: false, /* --------------- */ }}{ /* --------------- */ showCount(elem, count) { let _= this; if(_.isNull(elem) || _.isNull(count)) { throw new GhrcNullException('elem', 'count'); } elem.prepend("<span class='" + _.$.out.class + "' style='" + _.$.out.style + "'>" + count + "</span>"); } process() { let _= this; _.dbg('started for: ' + location.pathname); let url = _.getInfoAPI(); _.dbg('get info: ' + url); $.get(url, function(apidata) { $(_.$.pageFiles).each(function() { let root = $(this); let durl = root.attr('href'); if(durl.indexOf('releases/download') == -1) { return true; // means 'continue' statement } for(let idx in apidata) for(let asset in apidata[idx].assets) { let lnk = apidata[idx].assets[asset]; if(!lnk.browser_download_url.endsWith(durl)) { continue; }; _.dbg('insert data for #' + lnk.id + ': ' + durl); _.showCount(root, lnk.download_count); } }); }); } constructor(debug) { super(); this.$.debug = debug; this.process(); } getInfoAPI() { let l = this.$.usrprj.exec(location.pathname); return location.protocol + '//' + this.$.apiserver + '/repos/' + l[1] + '/' + l[2] + '/releases'; } dbg(msg, ...args) { if(!this.$.debug) { return; } let stamp = new Date().toISOString().substr(11, 12) + '] '; if(this.isNull(args) || args.length < 1) { console.log(stamp + msg); } else { console.log(stamp + msg, args); } } isNull(val) { return val == null || val === undefined; } }; class GhrcException { constructor(message, arg) { this.message = message; this.arg = arg; } } class GhrcNullException extends GhrcException { constructor(...args) { super("'" + args + "' cannot be null.", null); } } // ... let ghrс = new GhrCounter(false); // when async loading $(window).bind('pjax:success', function() { ghrс.process(); }); })();