Github anchor enhance

Enhance github repository link with badges

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name     Github anchor enhance
// @namespace https://github.com/NateScarlet/Scripts/tree/master/user-script
// @description Enhance github repository link with badges
// @grant    GM.xmlHttpRequest
// @run-at   document-end
// @include	 *
// @version   2023.08.27+41f23fa6
// ==/UserScript==

"use strict";
(() => {
  // src/github-anchor-enhance.user.ts
  var reservedUsername = /* @__PURE__ */ new Set([
    "topics",
    "search",
    "ghost",
    "pulls",
    "issues",
    "marketplace",
    "explore",
    "discover",
    "notifications",
    "new",
    "organizations",
    "settings",
    "site",
    "about",
    "contact",
    "pricing",
    "apps",
    "features",
    "password_reset",
    "trending",
    "collections",
    "events",
    "stars",
    "codespaces",
    "sponsors",
    "logout",
    "account"
  ]);
  var allBadgeClasses = ["added-stars-badge", "added-last-commit-badge"];
  var current = parseURL(location.href);
  function parseURL(rawURL) {
    const u = new URL(rawURL, document.baseURI);
    if (u.hostname !== "github.com") {
      return;
    }
    const match = /^\/([^/]+?)\/([^/]+?)(?:.git)?\/?$/.exec(u.pathname);
    if (!match) {
      return;
    }
    const owner = match[1];
    const repo = match[2];
    if (owner === current?.owner && repo === current.repo) {
      return;
    }
    if (reservedUsername.has(owner)) {
      return;
    }
    return {
      owner,
      repo
    };
  }
  async function appendBadge(el, className, url) {
    if (el.classList.contains(className)) {
      return;
    }
    return new Promise((resolve, reject) => {
      GM.xmlHttpRequest({
        method: "GET",
        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("");
              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, res) {
    await appendBadge(
      el,
      "added-stars-badge",
      `https://img.shields.io/github/stars/${res.owner}/${res.repo}.svg?style=social`
    );
  }
  async function appendLastCommitBadge(el, res) {
    await appendBadge(
      el,
      "added-last-commit-badge",
      `https://img.shields.io/github/last-commit/${res.owner}/${res.repo}.svg`
    );
  }
  (async function() {
    document.addEventListener(
      "mouseover",
      async (e) => {
        if (e.target instanceof HTMLAnchorElement) {
          const el = e.target;
          const res = parseURL(el.href);
          if (!res) {
            return;
          }
          try {
            await Promise.all([
              appendStarsBadge(el, res),
              appendLastCommitBadge(el, res)
            ]);
          } catch (err) {
            console.error(err);
          }
        }
      },
      {}
    );
  })();
})();