Modified Javascripts
跳转到导航
跳转到搜索
As claimed in Scattered Javascripts, I don’t know JavaScript, and thus, all of the following scripts were modified by AI.
Github Sort Content
Originally written by Rob Garrison here, then modified by Pharaoh2k here, then modified by Gemini for further revisions as follows.
github-sort-content.user.js
// ==UserScript==
// @name GitHub Sort Content
// @version 3.2.2
// @description A userscript that makes some lists & markdown tables sortable
// @license MIT
// @author Rob Garrison (modified by Pharaoh2k, then fixed by Gemini)
// @namespace https://github.com/Mottie
// @match https://github.com/*
// @match https://gist.github.com/*
// @run-at document-idle
// @grant GM.addStyle
// @grant GM_addStyle
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?updated=20180103
// @require https://cdnjs.cloudflare.com/ajax/libs/tinysort/3.2.5/tinysort.min.js
// @require https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=1108163
// @icon https://github.githubassets.com/pinned-octocat.svg
// @updateURL https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-sort-content.user.js
// @downloadURL https://raw.githubusercontent.com/Mottie/GitHub-userscripts/master/github-sort-content.user.js
// @supportURL https://github.com/Mottie/GitHub-userscripts/issues
// ==/UserScript==
(() => {
"use strict";
const sorts = ["asc", "desc"];
const icons = {
unsorted: color => `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="${color}">
<path d="M15 8H1l7-8zm0 1H1l7 7z" opacity=".2"/>
</svg>`,
ascending: color => `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="${color}">
<path d="M15 8H1l7-8z"/>
<path d="M15 9H1l7 7z" opacity=".2"/>
</svg>`,
descending: color => `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="${color}">
<path d="M15 8H1l7-8z" opacity=".2"/>
<path d="M15 9H1l7 7z"/>
</svg>`
};
const sortables = {
"repo-files": {
check: el => el.tagName === "TH" && el.closest(".Box-sc-g0xbh4-0"),
sort: el => initSortFiles(el),
css: {
unsorted: [
".Box-sc-g0xbh4-0 th"
],
tweaks: [
`body .Box-sc-g0xbh4-0 th {
text-align: left;
background-position: 3px center !important;
cursor: pointer;
padding-left: 22px !important;
}`
]
}
},
"repo-overview": {
check: el => el.tagName === "TH" && el.closest("table") && document.querySelector('.react-directory-row'),
sort: el => initSortOverview(el),
css: {
unsorted: [
"table th"
],
tweaks: [
`body table th {
text-align: left;
background-position: 3px center !important;
cursor: pointer;
padding-left: 22px !important;
}`
]
}
}
};
function getIcon(type, color) {
return "data:image/svg+xml;charset=UTF-8," +
encodeURIComponent(icons[type](color));
}
function needDarkTheme() {
let color = window.getComputedStyle(document.body).backgroundColor;
const rgb = (color || "")
.replace(/\s/g, "")
.match(/^rgba?\((\d+),(\d+),(\d+)/i);
if (rgb) {
const colors = rgb.slice(1).map(Number);
const brightest = Math.max(...colors);
return brightest < 128;
}
return false;
}
function getDirection(el) {
return (el.getAttribute("aria-sort") || "").includes(sorts[0])
? sorts[1]
: sorts[0];
}
function setDirection(els, currentElm, dir) {
els.forEach(elm => {
const cellDir = currentElm === elm ? `${dir}ending` : "none";
elm.setAttribute("aria-sort", cellDir);
});
}
function initSortFiles(el) {
removeSelection();
const dir = getDirection(el);
const table = el.closest("table");
let options = {
order: dir,
natural: true,
selector: `td:nth-child(${el.cellIndex + 1})`
};
if (el.querySelector('[title="Last commit date"]')) {
options = {
order: dir,
natural: true,
selector: ".react-directory-commit-age relative-time, .react-directory-commit-age .ghst-time",
attr: "datetime"
};
}
else if (el.querySelector('[class*="text-bold"]')) {
options.selector = ".react-directory-filename-cell a";
}
tinysort($$("tbody tr.react-directory-row", table), options);
setDirection($$("th", table), el, dir);
}
function initSortOverview(el) {
removeSelection();
const dir = getDirection(el);
const table = el.closest("table");
const colIndex = el.cellIndex;
let options = {
order: dir,
natural: true,
selector: `td:nth-child(${colIndex + 1})`
};
if (el.textContent.includes("Last commit date")) {
options = {
order: dir,
natural: true,
selector: ".react-directory-commit-age relative-time, .react-directory-commit-age .ghst-time",
attr: "datetime"
};
}
else if (el.textContent.includes("Name")) {
options.selector = ".react-directory-filename-cell a";
}
tinysort($$("tbody tr.react-directory-row", table), options);
setDirection($$("th", table), el, dir);
}
function removeSelection() {
const sel = window.getSelection ?
window.getSelection() :
document.selection;
if (sel) {
if (sel.removeAllRanges) {
sel.removeAllRanges();
} else if (sel.empty) {
sel.empty();
}
}
}
function $(str, el) {
return (el || document).querySelector(str);
}
function $$(str, el) {
return [...(el || document).querySelectorAll(str)];
}
function init() {
const color = needDarkTheme() ? "#ddd" : "#222";
const allUnsorted = [...sortables["repo-files"].css.unsorted, ...sortables["repo-overview"].css.unsorted];
const allTweaks = [...sortables["repo-files"].css.tweaks, ...sortables["repo-overview"].css.tweaks];
GM.addStyle(`
table thead th {
min-width: 120px !important;
padding: 8px !important;
}
table thead th .text-bold {
display: inline !important;
position: static !important;
width: initial !important;
height: initial !important;
clip: initial !important;
visibility: visible !important;
font-size: 12px !important;
line-height: 10px !important;
}
table thead th[colspan="2"] {
min-width: 200px !important;
}
${allUnsorted.join(", ")} {
cursor: pointer;
padding-left: 22px !important;
background-image: url(${getIcon("unsorted", color)}) !important;
background-repeat: no-repeat !important;
background-position: left center !important;
}
${allUnsorted.map(sel =>
`${sel}[aria-sort="ascending"] {
background-image: url(${getIcon("ascending", color)}) !important;
background-repeat: no-repeat !important;
}`
).join("\n")}
${allUnsorted.map(sel =>
`${sel}[aria-sort="descending"] {
background-image: url(${getIcon("descending", color)}) !important;
background-repeat: no-repeat !important;
}`
).join("\n")}
${allTweaks.join("\n")}`
);
document.body.addEventListener("click", event => {
const target = event.target;
if (target && target.nodeType === 1) {
Object.keys(sortables).some(item => {
const el = sortables[item].check(target, window.location);
if (el) {
sortables[item].sort(target);
event.preventDefault();
return true;
}
return false;
});
}
});
}
init();
})();
Github Static Time
Originally written by Rob Garrison here, then modified by Gemini as follows to be compatible with Github Sort Content.
github-static-time.user.js
// ==UserScript==
// @name GitHub Static Time
// @version 1.1.1
// @description A userscript that replaces relative times with a static time formatted as you like it
// @license MIT
// @author Rob Garrison (modified by Gemini)
// @namespace https://github.com/Mottie
// @match https://github.com/*
// @run-at document-idle
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @require https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment-with-locales.min.js
// @require https://greasyfork.org/scripts/28721-mutations/code/mutations.js?version=1108163
// @require https://greasyfork.org/scripts/398877-utils-js/code/utilsjs.js?version=1079637
// @require https://raw.githubusercontent.com/bradwoo8621/moment-taiwan/master/target/moment-taiwan.js
// @icon https://github.githubassets.com/pinned-octocat.svg
// @supportURL https://github.com/Mottie/GitHub-userscripts/issues
// @downloadURL https://update.greasyfork.org/scripts/29239/GitHub%20Static%20Time.user.js
// @updateURL https://update.greasyfork.org/scripts/29239/GitHub%20Static%20Time.meta.js
// ==/UserScript==
(() => {
"use strict";
let busy = false;
let timeFormat = GM_getValue("ghst-format", "LLL");
let locale = GM_getValue("ghst-locale", "en");
let useUTC = GM_getValue("ghst-utc", "false");
const locales = [
{ "abbr": "af", "name": "Afrikaans" },
{ "abbr": "sq", "name": "Albanian" },
{ "abbr": "ar", "name": "Arabic" },
{ "abbr": "ar-dz", "name": "Arabic (Algeria)" },
{ "abbr": "ar-kw", "name": "Arabic (Kuwait)" },
{ "abbr": "ar-ly", "name": "Arabic (Libya)" },
{ "abbr": "ar-ma", "name": "Arabic (Morocco)" },
{ "abbr": "ar-sa", "name": "Arabic (Saudi Arabia)" },
{ "abbr": "ar-tn", "name": "Arabic (Tunisia)" },
{ "abbr": "hy-am", "name": "Armenian" },
{ "abbr": "az", "name": "Azerbaijani" },
{ "abbr": "bm", "name": "Bambara" },
{ "abbr": "eu", "name": "Basque" },
{ "abbr": "be", "name": "Belarusian" },
{ "abbr": "bn", "name": "Bengali" },
{ "abbr": "bn-bd", "name": "Bengali (Bangladesh)" },
{ "abbr": "bs", "name": "Bosnian" },
{ "abbr": "br", "name": "Breton" },
{ "abbr": "bg", "name": "Bulgarian" },
{ "abbr": "my", "name": "Burmese" },
{ "abbr": "km", "name": "Cambodian" },
{ "abbr": "ca", "name": "Catalan" },
{ "abbr": "tzm", "name": "Central Atlas Tamazight" },
{ "abbr": "tzm-latn", "name": "Central Atlas Tamazight Latin" },
{ "abbr": "zh-cn", "name": "Chinese (China)" },
{ "abbr": "zh-hk", "name": "Chinese (Hong Kong)" },
{ "abbr": "zh-mo", "name": "Chinese (Macau)" },
{ "abbr": "zh-tw", "name": "Chinese (Taiwan)" },
{ "abbr": "cv", "name": "Chuvash" },
{ "abbr": "hr", "name": "Croatian" },
{ "abbr": "cs", "name": "Czech" },
{ "abbr": "da", "name": "Danish" },
{ "abbr": "nl", "name": "Dutch" },
{ "abbr": "nl-be", "name": "Dutch (Belgium)" },
{ "abbr": "en-au", "name": "English (Australia)" },
{ "abbr": "en-ca", "name": "English (Canada)" },
{ "abbr": "en-in", "name": "English (India)" },
{ "abbr": "en-ie", "name": "English (Ireland)" },
{ "abbr": "en-il", "name": "English (Israel)" },
{ "abbr": "en-nz", "name": "English (New Zealand)" },
{ "abbr": "en-sg", "name": "English (Singapore)" },
{ "abbr": "en-gb", "name": "English (United Kingdom)" },
{ "abbr": "en", "name": "English (United States)" },
{ "abbr": "eo", "name": "Esperanto" },
{ "abbr": "et", "name": "Estonian" },
{ "abbr": "fo", "name": "Faroese" },
{ "abbr": "fil", "name": "Filipino" },
{ "abbr": "fi", "name": "Finnish" },
{ "abbr": "fr", "name": "French" },
{ "abbr": "fr-ca", "name": "French (Canada)" },
{ "abbr": "fr-ch", "name": "French (Switzerland)" },
{ "abbr": "fy", "name": "Frisian" },
{ "abbr": "gl", "name": "Galician" },
{ "abbr": "ka", "name": "Georgian" },
{ "abbr": "de", "name": "German" },
{ "abbr": "de-at", "name": "German (Austria)" },
{ "abbr": "de-ch", "name": "German (Switzerland)" },
{ "abbr": "el", "name": "Greek" },
{ "abbr": "gu", "name": "Gujarati" },
{ "abbr": "he", "name": "Hebrew" },
{ "abbr": "hi", "name": "Hindi" },
{ "abbr": "hu", "name": "Hungarian" },
{ "abbr": "is", "name": "Icelandic" },
{ "abbr": "id", "name": "Indonesian" },
{ "abbr": "ga", "name": "Irish or Irish Gaelic" },
{ "abbr": "it", "name": "Italian" },
{ "abbr": "it-ch", "name": "Italian (Switzerland)" },
{ "abbr": "ja", "name": "Japanese" },
{ "abbr": "jv", "name": "Javanese" },
{ "abbr": "kn", "name": "Kannada" },
{ "abbr": "kk", "name": "Kazakh" },
{ "abbr": "tlh", "name": "Klingon" },
{ "abbr": "gom-deva", "name": "Konkani Devanagari script" },
{ "abbr": "gom-latn", "name": "Konkani Latin script" },
{ "abbr": "ko", "name": "Korean" },
{ "abbr": "ku", "name": "Kurdish" },
{ "abbr": "ky", "name": "Kyrgyz" },
{ "abbr": "lo", "name": "Lao" },
{ "abbr": "lv", "name": "Latvian" },
{ "abbr": "lt", "name": "Lithuanian" },
{ "abbr": "lb", "name": "Luxembourgish" },
{ "abbr": "mk", "name": "Macedonian" },
{ "abbr": "ms-my", "name": "Malay" },
{ "abbr": "ms", "name": "Malay" },
{ "abbr": "ml", "name": "Malayalam" },
{ "abbr": "dv", "name": "Maldivian" },
{ "abbr": "mt", "name": "Maltese (Malta)" },
{ "abbr": "mi", "name": "Maori" },
{ "abbr": "mr", "name": "Marathi" },
{ "abbr": "mn", "name": "Mongolian" },
{ "abbr": "me", "name": "Montenegrin" },
{ "abbr": "ne", "name": "Nepalese" },
{ "abbr": "se", "name": "Northern Sami" },
{ "abbr": "nb", "name": "Norwegian Bokmål" },
{ "abbr": "nn", "name": "Nynorsk" },
{ "abbr": "oc-lnc", "name": "Occitan, lengadocian dialecte" },
{ "abbr": "fa", "name": "Persian" },
{ "abbr": "pl", "name": "Polish" },
{ "abbr": "pt", "name": "Portuguese" },
{ "abbr": "pt-br", "name": "Portuguese (Brazil)" },
{ "abbr": "x-pseudo", "name": "Pseudo" },
{ "abbr": "pa-in", "name": "Punjabi (India)" },
{ "abbr": "ro", "name": "Romanian" },
{ "abbr": "ru", "name": "Russian" },
{ "abbr": "gd", "name": "Scottish Gaelic" },
{ "abbr": "sr", "name": "Serbian" },
{ "abbr": "sr-cyrl", "name": "Serbian Cyrillic" },
{ "abbr": "sd", "name": "Sindhi" },
{ "abbr": "si", "name": "Sinhalese" },
{ "abbr": "sk", "name": "Slovak" },
{ "abbr": "sl", "name": "Slovenian" },
{ "abbr": "es", "name": "Spanish" },
{ "abbr": "es-do", "name": "Spanish (Dominican Republic)" },
{ "abbr": "es-mx", "name": "Spanish (Mexico)" },
{ "abbr": "es-us", "name": "Spanish (United States)" },
{ "abbr": "sw", "name": "Swahili" },
{ "abbr": "sv", "name": "Swedish" },
{ "abbr": "tl-ph", "name": "Tagalog (Philippines)" },
{ "abbr": "tg", "name": "Tajik" },
{ "abbr": "tzl", "name": "Talossan" },
{ "abbr": "ta", "name": "Tamil" },
{ "abbr": "te", "name": "Telugu" },
{ "abbr": "tet", "name": "Tetun Dili (East Timor)" },
{ "abbr": "th", "name": "Thai" },
{ "abbr": "bo", "name": "Tibetan" },
{ "abbr": "tr", "name": "Turkish" },
{ "abbr": "tk", "name": "Turkmen" },
{ "abbr": "uk", "name": "Ukrainian" },
{ "abbr": "ur", "name": "Urdu" },
{ "abbr": "ug-cn", "name": "Uyghur (China)" },
{ "abbr": "uz", "name": "Uzbek" },
{ "abbr": "uz-latn", "name": "Uzbek Latin" },
{ "abbr": "vi", "name": "Vietnamese" },
{ "abbr": "cy", "name": "Welsh" },
{ "abbr": "yo", "name": "Yoruba Nigeria" },
{ "abbr": "ss", "name": "siSwati" }
];
const block = document.createElement("span");
block.className = "ghst-time time";
function staticTime(tempFormat) {
if (busy) {
return;
}
busy = true;
let selector = typeof tempFormat === "string"
? ".ghst-time"
: "relative-time, time-ago";
if ($(selector)) {
let indx = 0;
const els = $$(selector);
const len = els.length;
const loop = () => {
let el, time, node, formatted,
max = 0;
while (max < 20 && indx < len) {
if (indx >= len) {
return;
}
el = els[indx];
time = moment(el.getAttribute("datetime") || "");
if (el && time.isValid()) {
if (useUTC === "true") {
time = time.utc();
}
if (tempFormat) {
formatted = time.format(tempFormat);
el.textContent = formatted;
el.title = formatted;
} else {
formatted = time.format(timeFormat);
node = block.cloneNode(true);
node.setAttribute("datetime", el.getAttribute("datetime"));
node.textContent = formatted;
node.title = formatted;
if (el.parentElement) {
el.parentElement.replaceChild(node, el);
}
}
max++;
}
indx++;
}
if (indx < len) {
requestAnimationFrame(loop);
}
};
loop();
}
busy = false;
}
function addPanel() {
const div = document.createElement("div");
GM_addStyle(`
#ghst-settings { opacity:0; visibility:hidden; }
#ghst-settings.ghst-open { position:fixed; z-index:65535; top:0; bottom:0;
left:0; right:0; opacity:1; visibility:visible;
background:rgba(0, 0, 0, .5); }
#ghst-settings-inner { position:fixed; left:50%; top:50%; width:25rem;
transform:translate(-50%,-50%); box-shadow:0 .5rem 1rem #111;
color:#c0c0c0 }
#ghst-settings-inner .boxed-group-inner { height: 255px; }
#ghst-footer { clear:both; border-top:1px solid rgba(68, 68, 68, .3);
padding-top:5px; }
`);
div.id = "ghst-settings";
let options = "";
locales.forEach(loc => {
let sel = loc.abbr === locale ? " selected" : "";
options += `<option value="${loc.abbr}"${sel}>${loc.name}</option>`;
});
div.innerHTML = `
<div id="ghst-settings-inner" class="boxed-group">
<h3>GitHub Static Time Settings</h3>
<div class="boxed-group-inner">
<dl class="form-group flattened">
<dt>
<label for="ghst-locale">Select a locale</label>
</dt>
<dd>
<select id="ghst-locale" class="form-select float-right" value="${locale}">
${options}
</select>
<br>
</dd>
</dl>
<dl class="form-group flattened">
<dt>
<label for="ghst-utc">Show UTC time (use "z" in format below)</label>
</dt>
<dd>
<div class="form-checkbox">
<input id="ghst-utc" type="checkbox" class="float-right">
</div>
<br>
</dd>
</dl>
<dl class="form-group flattened">
<dt>
<label for="ghst-format">
Set <a href="https://momentjs.com/docs/#/displaying/format/" target="_blank">
MomentJS
</a> format (e.g. "MMMM Do YYYY, h:mm A"):
</label>
</dt>
<dd>
<input id="ghst-format" type="text" class="form-control" value="${timeFormat}"/>
</dd>
</dl>
<div id="ghst-footer">
<button type="button" id="ghst-cancel" class="btn btn-sm float-right">Cancel</button>
<button type="button" id="ghst-save" class="btn btn-sm float-right">Save</button>
</div>
</div>
</div>`;
$("body").appendChild(div);
$("#ghst-utc").checked = useUTC === "true";
on($("#ghst-settings"), "click", closePanel);
on($("body"), "keyup", event => {
if (
event.key === "Escape" &&
$("#ghst-settings").classList.contains("ghst-open")
) {
closePanel(event);
return false;
} else if (event.key === "Enter" && event.shiftKey) {
closePanel();
update("save");
}
});
on($("#ghst-settings-inner"), "click", event => {
event.stopPropagation();
});
on($("#ghst-save"), "click", () => {
closePanel();
update("save");
});
on($("#ghst-locale"), "change", update);
on($("#ghst-utc"), "change", update);
on($("#ghst-format"), "change", update);
on($("#ghst-cancel"), "click", closePanel);
}
function closePanel(event) {
$("#ghst-settings").classList.remove("ghst-open");
if (event) {
return update("revert");
}
}
function update(mode) {
if (mode === "revert") {
$("#ghst-locale").value = locale;
$("#ghst-format").value = timeFormat;
$("#ghst-utc").checked = useUTC === "true";
}
let loc = $("#ghst-locale").value || "en";
let time = $("#ghst-format").value || "LLL";
let utc = $("#ghst-utc").checked ? "true" : "false";
if (mode === "save") {
timeFormat = time;
locale = loc;
useUTC = utc;
GM_setValue("ghst-format", timeFormat);
GM_setValue("ghst-locale", locale);
GM_setValue("ghst-utc", useUTC);
}
moment.locale(loc);
staticTime(time);
return false;
}
function init() {
addPanel();
moment.locale(locale);
staticTime();
}
GM_registerMenuCommand("Set GitHub static time format", () => {
$("#ghst-settings").classList.add("ghst-open");
});
document.addEventListener("ghmo:container", () => {
setTimeout(() => {
staticTime();
}, 100);
});
document.addEventListener("ghmo:preview", staticTime);
init();
})();