Add repo/branch links to GitHub's "Comparing Changes" page

This adds a link to the fork's branch on the GitHub "Comparing changes" page (AKA the "Create a Pull Request" page). See https://stackoverflow.com/questions/77623282/how-do-i-get-my-remote-branch-url-from-the-github-create-pull-request-page for more details.

Устаревшая версия за 09.12.2023. Перейдите к последней версии.

// ==UserScript==
// @name         Add repo/branch links to GitHub's "Comparing Changes" page
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  This adds a link to the fork's branch on the GitHub "Comparing changes" page (AKA the "Create a Pull Request" page). See https://stackoverflow.com/questions/77623282/how-do-i-get-my-remote-branch-url-from-the-github-create-pull-request-page for more details.
// @author       DanKaplanSES
// @match        https://github.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=github.com
// @require      https://code.jquery.com/jquery-3.7.1.min.js
// @grant        none
// @license MIT
// ==/UserScript==

const browseRepoHtml = `<div class="browse-repo"><a href="#" target="_blank">Browse Repo</a></div>`;
const browseBranchHtml = `<div class="browse-branch"><a href="#" target="_blank">Browse Branch</a></div>`;

jQuery.noConflict(true)(function ($) {
  function modifyPage() {
    if (location.pathname.indexOf(`/compare/`) === -1) {
      return;
    }
    const isPageAlreadyModified = $(`#browse-link-0`).length > 0;
    if (isPageAlreadyModified) {
      return;
    }

    $(`.range-cross-repo-pair details:visible`).wrap(
      `<div class="details-container"></div>`
    )

    const detailsContainers = $(`.details-container`);
    const dropdownCount = detailsContainers.length;
    detailsContainers.each(function (index) {
      const html = linkHtml(dropdownCount, index);
      const href = linkHref(dropdownCount, index);
      console.error(`html`, html, `href`, href, `dropdownCount`, dropdownCount, `this`, this);
      $(this)
        .css({ 'display': `inline-block` })
        .append(html)
        .css({ 'text-align': `center` })
        .find(`a`)
        .attr({ id: `browse-link-${index}`, href });
    });
    $(`.range-editor .pre-mergability, .range-editor .d-inline-block`).css({
      'vertical-align': `top`,
    });
  }

  function linkHtml(dropdownCount, index) {
    if (dropdownCount === 2) {
      return browseBranchHtml;
    }

    return isEven(index) ? browseRepoHtml : browseBranchHtml;
  }

  function linkHref(dropdownCount, index) {
    if (dropdownCount === 2) {
      const dropdownLabelIndex = index * 2 + 1; // Either 1 or 3: There are 4 dropdown labels on the page. 2 are hidden. This is the 0-based index of the dropdown we are modifying.
      return hrefString('branch', dropdownLabelIndex);
    }

    const hrefType = isEven(index) ? 'repo' : 'branch';
    return hrefString(hrefType, index);
  }

  function hrefString(hrefType, index) {
      console.error(`hrefType`, hrefType, `index`, index);
    switch (hrefType) {
      case 'repo':
        return `/` + $(`.css-truncate-target`)[index].textContent;
      case 'branch':
        return (
          `/` +
          $(`.css-truncate-target`)[index - 1].textContent +
          `/tree/` +
          $(`.css-truncate-target`)[index].textContent
        );
      default:
        throw new Error(`Unexpected hrefType: ${hrefType}`);
    }
  }

  function isEven(num) {
    return num % 2 === 0;
  }

  const isPageLoaded = $(`.range-cross-repo-pair details`).length > 0;
  if (isPageLoaded) {
    modifyPage();
  }

  setInterval(modifyPage, 1500);
});