12/8/2023, 9:09:51 PM
当前为
// ==UserScript==
// @name GitHub: Redirect forked repo links to own repo
// @namespace Violentmonkey Scripts
// @match https://github.com/*
// @grant none
// @version 0.1.1
// @author CY Fung
// @description 12/8/2023, 9:09:51 PM
// @run-at document-start
// @license MIT
// ==/UserScript==
/**
*
* This is to change links in markdown files from the original repo links to your forked repo links
*
**/
(() => {
let rafPromise = null;
const rafFn = (typeof webkitRequestAnimationFrame !== 'undefined' ? webkitRequestAnimationFrame : requestAnimationFrame).bind(window); // eslint-disable-line no-undef, no-constant-condition
const getRafPromise = () => rafPromise || (rafPromise = new Promise(resolve => {
rafFn(hRes => {
rafPromise = null;
resolve(hRes);
});
}));
const matcher = h => typeof h == 'string' && h.length > 19 && h.startsWith('https://github.com/') && /^https\:\/\/github\.com\/([\w\d\-\.]+)\/([\w\d\-\.]+)/.exec(h);
const pageInfo = {
ready: false,
matched: false,
owner: '',
repo: '',
originalOwner: '',
originalRepo: '',
url: '',
};
const PromiseExternal = ((resolve_, reject_) => {
const h = (resolve, reject) => { resolve_ = resolve; reject_ = reject };
return class PromiseExternal extends Promise {
constructor(cb = h) {
super(cb);
if (cb === h) {
/** @type {(value: any) => void} */
this.resolve = resolve_;
/** @type {(reason?: any) => void} */
this.reject = reject_;
}
}
};
})();
let pageOriginalP = new PromiseExternal();
document.addEventListener('DOMContentLoaded', () => {
// Define the XPath expression
var xpathExpression = "//span[contains(text(), 'forked from')]";
// Use document.evaluate to find the matching element
var result = document.evaluate(xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
var spanElement = result.singleNodeValue;
// Check if a matching element was found
if (spanElement instanceof Element) {
setTimeout(() => {
const a = spanElement.querySelector('a[href]');
if (a) {
const h = a.href;
let m = matcher(h);
if (m) {
pageInfo.originalOwner = m[1];
pageInfo.originalRepo = m[2];
pageInfo.originalRepoUrl = `https://github.com/${pageInfo.originalOwner}/${pageInfo.originalRepo}/`;
pageOriginalP.resolve();
}
}
}, 1);
}
}, false);
let qk = 0;
let ck = 0;
const process = async () => {
let qt = ++qk;
await pageOriginalP.then();
if (qt !== qk) return;
let ct = ++ck;
await getRafPromise().then();
if (ct !== ck) return;
for (const s of document.querySelectorAll(`a[href^="${pageInfo.originalRepoUrl}"]`)) {
const h = s.getAttribute('href');
let m = matcher(h);
if (m) {
s.setAttribute('href', h.replace(`${pageInfo.originalRepoUrl}`, `${pageInfo.repoUrl}`))
}
}
}
const mo = new MutationObserver((entries) => {
if (!pageInfo.ready) {
pageInfo.ready = true;
let pageUrl = `${location.origin}${location.pathname}`;
pageInfo.url = pageUrl;
let m = matcher(pageUrl);
if (m) {
pageInfo.matched = true;
pageInfo.owner = m[1];
pageInfo.repo = m[2];
pageInfo.repoUrl = `https://github.com/${pageInfo.owner}/${pageInfo.repo}/`;
}
}
if (pageInfo.matched) {
process();
}
});
mo.observe(document, { subtree: true, childList: true });
})();