Github anchor enhance

Enhance all github link with badges

Version vom 09.11.2019. Aktuellste Version

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @namespace https://github.com/NateScarlet/Scripts/tree/master/user-script
// @name     Github anchor enhance
// @description Enhance all github link with badges
// @version  17
// @grant    GM.xmlHttpRequest
// @run-at   document-end
// @include	 *
// ==/UserScript==
const reservedUsername = [
    "topics",
    "search",
    "ghost",
    "pulls",
    "issues",
    "marketplace",
    "explore",
    "discover",
    "notifications",
    "new",
    "organizations",
    "settings",
    "site",
    "about",
    "contact",
    "pricing",
    "apps",
    "features",
    "password_reset",
];
const allBadgeClasses = [
    "added-stars-badge",
    "added-last-commit-badge",
    "added-followers-badge",
];
class URLParseResult {
    constructor({ user, repo }) {
        this.user = user;
        this.repo = repo;
    }
    equals(other) {
        return other.repo === this.repo && other.user === this.user;
    }
}
URLParseResult.EMPTY = new URLParseResult({});
function parseURL(v) {
    const match = v.match(/^https?:\/\/github.com\/([^/]*?)(?:\/([^/]*?))?(?:\.git)?(?:[#?].*)?(?:$|\/)/);
    if (!match) {
        return URLParseResult.EMPTY;
    }
    if (reservedUsername.includes(match[1])) {
        return URLParseResult.EMPTY;
    }
    return new URLParseResult({
        user: match[1],
        repo: match[2],
    });
}
async function appendBadge(el, className, url) {
    if (el.classList.contains(className)) {
        return;
    }
    return new Promise((resolve, reject) => {
        GM.xmlHttpRequest({
            method: "GET",
            url: url,
            onload: resp => {
                if (resp.status === 200) {
                    if (!el.classList.contains(className)) {
                        const img = document.createElement("img");
                        img.src = `data:image/svg+xml;base64,${btoa(resp.response)}`;
                        const containerClassNames = [
                            "natescarlet-gmail-com",
                            "badge-container",
                        ];
                        const selector = containerClassNames.map(i => "." + i).join("");
                        /** @type {HTMLElement} */
                        const container = el.querySelector(selector) || document.createElement("span");
                        el.appendChild(container);
                        container.classList.add(...containerClassNames);
                        container.append(img);
                        img.style.order = allBadgeClasses.indexOf(className).toString();
                        container.style.display = "inline-flex";
                        el.classList.add(className);
                    }
                    resolve();
                }
                reject(`${resp.status}: ${url}`);
            },
            onerror: reject,
        });
    });
}
async function appendStarsBadge(el) {
    const { repo, user } = parseURL(el.href);
    if (!(user && repo)) {
        return;
    }
    await appendBadge(el, "added-stars-badge", `https://img.shields.io/github/stars/${user}/${repo}.svg?style=social`);
}
async function appendLastCommitBadge(el) {
    const { repo, user } = parseURL(el.href);
    if (!(user && repo)) {
        return;
    }
    await appendBadge(el, "added-last-commit-badge", `https://img.shields.io/github/last-commit/${user}/${repo}.svg`);
}
async function appendFollowersBadge(el) {
    const { user } = parseURL(el.href);
    if (!user) {
        return;
    }
    await appendBadge(el, "added-followers-badge", `https://img.shields.io/github/followers/${user}.svg?style=social`);
}
(async function () {
    document.addEventListener("mouseover", async (e) => {
        if (e.target instanceof HTMLAnchorElement) {
            const el = e.target;
            if (parseURL(location.href).equals(parseURL(el.href))) {
                // Skip self link
                return;
            }
            try {
                await Promise.all([
                    appendStarsBadge(el),
                    appendLastCommitBadge(el),
                    appendFollowersBadge(el),
                ]);
            }
            catch (err) {
                console.error(err);
            }
        }
    }, {});
})();