GitHub First Commit

Add a link to a GitHub repo's first commit

Stan na 26-05-2024. Zobacz najnowsza wersja.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

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

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

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.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name          GitHub First Commit
// @description   Add a link to a GitHub repo's first commit
// @author        chocolateboy
// @copyright     chocolateboy
// @version       4.0.0
// @namespace     https://github.com/chocolateboy/userscripts
// @license       GPL
// @include       https://github.com/
// @include       https://github.com/*
// @grant         GM_log
// @noframes
// ==/UserScript==

// NOTE This file is generated from src/github-first-commit.user.ts and should not be edited directly.

"use strict";
(() => {
  // src/lib/observer.ts
  var DUMMY_MUTATIONS = [];
  var INIT = { childList: true, subtree: true };
  var observe = (target, ...args) => {
    const [init, callback] = args.length === 1 ? [INIT, args[0]] : args;
    const $callback = (mutations, observer2) => {
      observer2.disconnect();
      const result = callback(mutations, observer2);
      if (!result) {
        observer2.observe(target, init);
      }
    };
    const observer = new MutationObserver($callback);
    queueMicrotask(() => $callback(DUMMY_MUTATIONS, observer));
    return observer;
  };

  // src/github-first-commit.user.ts
  // @license       GPL
  var ID = "first-commit";
  var LOCATION = 'meta[name="analytics-location"][content]';
  var USER_REPO = 'meta[name="octolytics-dimension-repository_network_root_nwo"][content]';
  var $ = document;
  var openFirstCommit = (user, repo) => {
    return fetch(`https://api.github.com/repos/${user}/${repo}/commits`).then((res) => Promise.all([res.headers.get("link"), res.json()])).then(([link, commits]) => {
      if (!link) {
        return commits;
      }
      const lastPage = link.match(/^.+?<([^>]+)>;/)[1];
      return fetch(lastPage).then((res) => res.json());
    }).then((commits) => {
      if (Array.isArray(commits)) {
        location.href = commits[commits.length - 1].html_url;
      } else {
        console.error(commits);
      }
    });
  };
  observe($.body, () => {
    const path = $.querySelector(LOCATION)?.content;
    const isRepoPage = path === "/<user-name>/<repo-name>";
    if (!isRepoPage) {
      return;
    }
    if ($.getElementById(ID)) {
      return;
    }
    const historyIcon = $.querySelector("svg.octicon-history");
    if (!historyIcon) {
      return;
    }
    const commitHistory = historyIcon.closest("div");
    const container = commitHistory.parentElement;
    const firstCommit = commitHistory.cloneNode(true);
    const label = firstCommit.querySelector(':scope [data-component="text"] > *');
    const header = firstCommit.querySelector(":scope h2");
    const link = firstCommit.querySelector(":scope a[href]");
    const [user, repo] = $.querySelector(USER_REPO).getAttribute("content").split("/");
    firstCommit.id = ID;
    header.textContent = label.textContent = "1st Commit";
    link.removeAttribute("href");
    link.setAttribute("aria-label", "First commit");
    firstCommit.addEventListener("click", (e) => {
      e.preventDefault();
      e.stopPropagation();
      label.textContent = "Loading...";
      openFirstCommit(user, repo);
    }, { once: true });
    container.appendChild(firstCommit);
  });
})();