javascript:(function(){function f(a){var g=document.querySelector('div[role="rowheader"] a[title="'+a.name+'"]').closest('div[role="row"]').lastElementChild,c=document.createElement("div");c.style.width="5em";"file"===a.type&&(c.textContent=(a.size/1024).toLocaleString("en-US",{minimumFractionDigits:1,maximumFractionDigits:1})+" KB",c.style.textAlign="right",c.style.whiteSpace="nowrap");g.insertAdjacentElement("beforebegin",c)}var b=window.location.pathname.split("/"),d=b[1],h=b[2],e=b[4];b=b.slice(5);d=["https://api.github.com/repos",d,h,"contents"].concat(b||[]).join("/")+(e?"?ref="+e:"");console.log(d);fetch(d).then(function(a){return a.json()}).then(function(a){return Array.isArray(a)?a.forEach(f):console.warn(a)})})();
未压缩源代码:
(function () {
"use strict";
//Parse the current GitHub repo url. Examples:
// Repo root: /Sphinxxxx/vanilla-picker
// Subfolder: /Sphinxxxx/vanilla-picker/tree/master/src/css
// Subfolder at commit: /Sphinxxxx/vanilla-picker/tree/382231756aac75a49f046ccee1b04263196f9a22/src/css
// Subfolder at tag: /Sphinxxxx/vanilla-picker/tree/v2.2.0/src/css
//
//If applicable, the name of the commit/branch/tag is always the 4th element in the url path.
//Here, we put that in the "ref" variable:
const [/* Leading slash */, owner, repo, /* "tree" */, ref, ...path] = window.location.pathname.split('/');
//Create the URL to query GitHub's API: https://developer.github.com/v3/repos/contents/#get-contents
//Example:
// https://api.github.com/repos/Sphinxxxx/vanilla-picker/contents/src/css?ref=382231756aac75a49f046ccee1b04263196f9a22
const query = ['https://api.github.com/repos', owner, repo, 'contents'].concat(path || []),
url = query.join('/') + (ref ? '?ref=' + ref : '');
console.log(url);
//https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
fetch(url).then(r => r.json())
.then(j => Array.isArray(j) ? j.forEach(handleFileInfo) : console.warn(j));
function handleFileInfo(info) {
//console.log(info);
const link = document.querySelector(`div[role="rowheader"] a[title="${info.name}"]`);
const timeCol = link.closest('div[role="row"]').lastElementChild;
const sizeCol = document.createElement('div');
sizeCol.style.width = '5em';
if(info.type === 'file') {
//https://dev59.com/P3E85IYBdhLWcg3wMAfc#17663871
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Parameters
sizeCol.textContent = (info.size/1024).toLocaleString('en-US', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' KB';
sizeCol.style.textAlign = 'right';
sizeCol.style.whiteSpace = 'nowrap';
}
timeCol.insertAdjacentElement('beforebegin', sizeCol);
}
})();
从第一段代码创建一个书签脚本,或者只需将其复制粘贴到您的浏览器控制台中。
你可以使用调用GitHub API的JavaScript书签小工具强制文件大小显示。
2023年的GitHub现在有两种类型的文件表格(一种是基于<table>
,另一种是基于<div>
),因此我准备了这个新的书签小工具,在修改之前检测使用的样式:
javascript:(function e(){let t=[...document.querySelectorAll('div[role="row"]')],n;if(t.length||(t=[...document.querySelectorAll("tbody tr")],n=document.querySelector("thead tr")),(t=t.slice(1)).length&&"github.com"===document.location.host){let[,l,i,r,o,...c]=window.location.pathname.split("/");if(i&&("tree"===r||!r)){let s=["https://api.github.com/repos",l,i,"contents"].concat(c||[]).join("/")+(o?"?ref="+o:"");console.log(s),fetch(s).then(e=>e.json()).then(e=>{let l=new Map;if(e.forEach(e=>l.set(e.name,e)),n&&"Size"!==n.children[1].innerText){let i=document.createElement("th");i.style.width="6em",i.textContent="Size",n.firstElementChild.insertAdjacentElement("afterend",i)}for(let r of t){let o=r.children[n?0:1],c=o.innerText;c.indexOf("\n")>0&&(c=c.slice(0,c.indexOf("\n")));let s=l.get(c),d=document.createElement(n?"td":"div");d.style.width="6em",d.className=o.className,d.innerText=a(s?.size),o.insertAdjacentElement("afterend",d)}})}else console.error("GITHUB PATH NOT UNDERSTOOD")}else console.error("GITHUB TABLE NOT FOUND; can't add file sizes");function a(e){if(!e)return null==e?"–":"0";if(e<0)return"-"+a(-e);let t;return e<1024?e+" B":(e<1048576?(t=" KiB",e/=1024):e<1073741824?(t=" MiB",e/=1048576):(t=" GiB",e/=1073741824),e.toFixed(1)+t)}})();
请参考此处的说明制作书签。
以下是原始未压缩代码:
(function addSizes() {
// Sometimes each row is like `<div role="row" class="Box-row...">` with no column headers
// e.g. https://github.com/qwertie/ecsharp
// Sometimes each row is like `<tr class="react-directory-row">` with header in `<thead...><tr...>`
// e.g. https://github.com/qwertie/ecsharp/tree/master/Main
// Look for the first kind of rows; if not found, look for the other kind
let rows = [...document.querySelectorAll(`div[role="row"]`)], header;
if (!rows.length) {
rows = [...document.querySelectorAll(`tbody tr`)];
header = document.querySelector(`thead tr`);
}
rows = rows.slice(1);
if (rows.length && document.location.host === 'github.com') {
// Parse path after https://github.com, e.g.
// /username/repo
// /username/repo/tree/branch-name
// /username/repo/tree/branch-name/folder-name
let [/* Leading slash */, owner, repo, __tree__, branch, ...path] = window.location.pathname.split('/');
if (repo && (__tree__ === 'tree' || !__tree__)) {
let query = ['https://api.github.com/repos', owner, repo, 'contents']
.concat(path || []).join('/') + (branch ? '?ref=' + branch : '');
console.log(query);
// The GitHub API will returns an array of objects like
// [{ "name": "file.py", "path": "folder/file.py", "size": 5226, ... }, ...]
fetch(query).then(r => r.json()).then(files => {
// Index the results by file name
let fileMap = new Map();
files.forEach(file => fileMap.set(file.name, file));
// If there is a header row, add a header cell for the file size. Note:
// If user browses to another folder, the 'Size' header column still exists
// but no file sizes. In that case, avoid adding another 'Size' column.
if (header && header.children[1].innerText !== 'Size') {
let sizeCol = document.createElement('th');
sizeCol.style.width = '6em';
sizeCol.textContent = 'Size';
header.firstElementChild.insertAdjacentElement('afterend', sizeCol);
}
// For each row of the table: get the file name, look it up in
// fileMap, get the file size, and insert a size column.
for (let row of rows) {
let nameCol = row.children[header ? 0 : 1];
let name = nameCol.innerText;
if (name.indexOf('\n') > 0) name = name.slice(0, name.indexOf('\n'));
let file = fileMap.get(name);
let sizeCol = document.createElement(header ? 'td' : 'div');
sizeCol.style.width = '6em';
sizeCol.className = nameCol.className;
sizeCol.innerText = formatFileSize(file?.size);
nameCol.insertAdjacentElement('afterend', sizeCol);
}
});
} else {
console.error('GITHUB PATH NOT UNDERSTOOD');
}
} else {
console.error("GITHUB TABLE NOT FOUND; can't add file sizes");
}
function formatFileSize(size) {
if (!size) return size == null ? '–' : '0';
if (size < 0) return '-' + formatFileSize(-size);
let suffix;
if (size < 1024) {
return size + ' B';
} else if (size < 1024*1024) {
suffix = ' KiB';
size /= 1024;
} else if (size < 1024*1024*1024) {
suffix = ' MiB';
size /= 1024*1024;
} else {
suffix = ' GiB';
size /= 1024*1024*1024;
}
return size.toFixed(1) + suffix;
};
})();
不,GitHub文件浏览器无法进行这样的配置。
要获取额外信息意味着为GitHub传输大量额外数据(对于每个存储库的每个页面),因此我不确定您是否会很快看到此功能。
匹配被标记为XML并且恰好有100个字节的单词“element”的代码。
在 @Sphinxxx 的回答之后更新了脚本/书签,现在加上了注释:
书签:
!function(){"use strict";const[,t,e,,n,...i]=window.location.pathname.split("/"),o=["https://api.github.com/repos",t,e,"contents"].concat(i||[]).join("/")+(n?"?ref="+n:"");function r(t){var e=null,n=null;if("file"===t.type){const i=`div[role="rowheader"] a[title="${t.name}"]`;e=document.querySelector(i).closest('div[role="row"]').lastElementChild,(n=document.createElement("div")).style.width="5em",n.textContent=(t.size/1024).toLocaleString("en-US",{minimumFractionDigits:1,maximumFractionDigits:1})+" KB",n.style.textAlign="right",n.style.whiteSpace="nowrap",e.insertAdjacentElement("beforebegin",n)}}fetch(o).then((t=>t.json())).then((t=>Array.isArray(t)?t.forEach(r):console.warn("Not an array of files: ",t)))}();
使用方法:
右键点击,复制链接,粘贴到地址栏(或书签链接中),在不加引号的情况下添加“javascript:”,按回车键
适用于新的 GitHub 布局,左侧为文件夹树,右侧为文件内容:
!function(){"use strict";const[,t,e,,n,...i]=window.location.pathname.split("/"),o=["https://api.github.com/repos",t,e,"contents"].concat(i||[]).join("/")+(n?"?ref="+n:"");function r(t){var e=null,n=null;if("file"===t.type){const i=`div[title="${t.name}"]`;e=document.querySelector(i).closest('tr[class="react-directory-row"]').lastElementChild,(n=document.createElement("td")).style.width="5em",n.innerHTML=(t.size/1024).toLocaleString("en-US",{minimumFractionDigits:1,maximumFractionDigits:1})+" KB",e.insertAdjacentElement("beforebegin",n)}}fetch(o).then((t=>t.json())).then((t=>Array.isArray(t)?t.forEach(r):console.warn("Not an array of files: ",t)))}();
脚本1:
(function () {
"use strict";
//Parse the current GitHub repo url. Examples:
// Repo root: /Sphinxxxx/vanilla-picker
// Subfolder: /Sphinxxxx/vanilla-picker/tree/master/src/css
// Subfolder at commit: /Sphinxxxx/vanilla-picker/tree/382231756aac75a49f046ccee1b04263196f9a22/src/css
// Subfolder at tag: /Sphinxxxx/vanilla-picker/tree/v2.2.0/src/css
//
//If applicable, the name of the commit/branch/tag is always the 4th element in the url path.
//Here, we put that in the "ref" variable:
const [/* Leading slash */, owner, repo, /* "tree" */, ref, ...path] = window.location.pathname.split('/'); // split url and store pieces into constants.
//Create the URL to query GitHub's API: https://developer.github.com/v3/repos/contents/#get-contents
//Example:
// https://api.github.com/repos/Sphinxxxx/vanilla-picker/contents/src/css?ref=382231756aac75a49f046ccee1b04263196f9a22;
const query = ['https://api.github.com/repos', owner, repo, 'contents'].concat(path || []),
url = query.join('/') + (ref ? '?ref=' + ref : '');
//https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
fetch(url).then(r => r.json())
.then(j => Array.isArray(j) ? j.forEach(handleFileInfo) : console.warn("Not an array of files: ",j));
function handleFileInfo(info) {
var timeCol = null;
var sizeCol = null;
var link = "";
var QR = "";
if(info.type === 'file') { // skip folders
const QR = `div[role="rowheader"] a[title="${info.name}"]`; // select the cell containing the file name
link = document.querySelector(QR);
///// Climb along the html hierarchy until it finds a DIV named "row",
///// and get last element (last cell of row), i.e. the date column:
timeCol = link.closest('div[role="row"]').lastElementChild;
///// Create label for file size
sizeCol = document.createElement('div');
sizeCol.style.width = '5em';
//https://dev59.com/P3E85IYBdhLWcg3wMAfc#17663871
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Parameters
sizeCol.textContent = (info.size/1024).toLocaleString('en-US', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' KB';
sizeCol.style.textAlign = 'right';
sizeCol.style.whiteSpace = 'nowrap';
///// Insert new label before last element of row:
timeCol.insertAdjacentElement('beforebegin', sizeCol);
} else {
// skip folders
}
}
})();
脚本2:
(function () {
"use strict";
//Parse the current GitHub repo url. Examples:
// Repo root: /Sphinxxxx/vanilla-picker
// Subfolder: /Sphinxxxx/vanilla-picker/tree/master/src/css
// Subfolder at commit: /Sphinxxxx/vanilla-picker/tree/382231756aac75a49f046ccee1b04263196f9a22/src/css
// Subfolder at tag: /Sphinxxxx/vanilla-picker/tree/v2.2.0/src/css
//
//If applicable, the name of the commit/branch/tag is always the 4th element in the url path.
//Here, we put that in the "ref" variable:
const [/* Leading slash */, owner, repo, /* "tree" */, ref, ...path] = window.location.pathname.split('/'); // split url and store pieces into constants.
//Create the URL to query GitHub's API: https://developer.github.com/v3/repos/contents/#get-contents
//Example:
// https://api.github.com/repos/Sphinxxxx/vanilla-picker/contents/src/css?ref=382231756aac75a49f046ccee1b04263196f9a22;
const query = ['https://api.github.com/repos', owner, repo, 'contents'].concat(path || []),
url = query.join('/') + (ref ? '?ref=' + ref : '');
//https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
fetch(url).then(r => r.json())
.then(j => Array.isArray(j) ? j.forEach(handleFileInfo) : console.warn("Not an array of files: ",j));
function handleFileInfo(info) {
var timeCol = null;
var sizeCol = null;
var link = "";
var QR = "";
if(info.type === 'file') { // skip folders
const QR = `div[title="${info.name}"]`; // select the cell containing the file name
link = document.querySelector(QR);
///// Climb along the html hierarchy until it finds a DIV named "row",
///// and get last element (last cell of row), i.e. the date column:
timeCol = link.closest('tr[class="react-directory-row"]').lastElementChild;
///// Create label for file size
sizeCol = document.createElement('td');
sizeCol.style.width = '5em';
//https://dev59.com/P3E85IYBdhLWcg3wMAfc#17663871
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Parameters
sizeCol.innerHTML = (info.size/1024).toLocaleString('en-US', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' KB';
//sizeCol.style.textAlign = 'right';
//sizeCol.style.whiteSpace = 'nowrap';
///// Insert new label before last element of row:
timeCol.insertAdjacentElement('beforebegin', sizeCol);
} else {
// skip folders
}
}
})();