Github anchor enhance

Enhance all github link with badges

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

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name     Github anchor enhance
// @version  12
// @grant    GM.xmlHttpRequest
// @run-at   document-idle
// @include	 *
// @namespace https://greasyfork.org/users/17676
// @description Enhance all github link with badges
// ==/UserScript==

(async function() {
  document.addEventListener(
    'mouseover',
    async e => {
      if (e.target instanceof HTMLAnchorElement) {
        const el = e.target;
        const u = new URL(el.href);
        if (
          location.hostname === u.hostname &&
          location.pathname === u.pathname
        ) {
          // Skip self link
          return;
        }
        try {
          await Promise.all([
            appendStarsBadge(el),
            appendLastCommitBadge(el),
            appendFollowersBadge(el),
          ]);
        } catch (err) {
          console.error(err);
        }
      }
    },
    {}
  );
})();

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',
];

/**
 *
 * @param {HTMLAnchorElement} el
 */
async function appendStarsBadge(el) {
  const match =
    el.href && el.href.match(/https:\/\/github.com\/([^/]+)\/([^/?]+)$/);

  if (match) {
    const [, user, repository] = match;
    if (reservedUsername.includes(user)) {
      return;
    }
    await appendBadge(
      el,
      'added-stars-badge',
      `https://img.shields.io/github/stars/${user}/${repository}.svg?style=social`
    );
  }
}
/**
 *
 * @param {HTMLAnchorElement} el
 */
async function appendLastCommitBadge(el) {
  const match =
    el.href && el.href.match(/https:\/\/github.com\/([^/]+)\/([^/?]+)$/);

  if (match) {
    const [, user, repository] = match;
    if (reservedUsername.includes(user)) {
      return;
    }
    await appendBadge(
      el,
      'added-last-commit-badge',
      `https://img.shields.io/github/last-commit/${user}/${repository}.svg`
    );
  }
}
/**
 *
 * @param {HTMLAnchorElement} el
 */
async function appendFollowersBadge(el) {
  const match = el.href && el.href.match(/https:\/\/github.com\/([^/?]+)$/);

  if (match) {
    const [, user] = match;
    if (reservedUsername.includes(user)) {
      return;
    }
    await appendBadge(
      el,
      'added-followers-badge',
      `https://img.shields.io/github/followers/${user}.svg?style=social`
    );
  }
}

/**
 * @param {HTMLElement} el
 * @param {string} className
 * @param {string} url
 */
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,
    });
  });
}