Go to Github Releases Page

Add a quick link button to navigate to GitHub repository releases page

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name                    Go to Github Releases Page
// @name:zh-CN              跳转到 Github Releases 页面
// @namespace               https://github.com/xlsama/tampermonkey-scripts
// @version                 0.1.0
// @author                  xlsama
// @description             Add a quick link button to navigate to GitHub repository releases page
// @description:zh-CN       在 GitHub 仓库页面添加快速跳转到 Releases 页面的按钮
// @homepageURL             https://github.com/xlsama/tampermonkey-scripts
// @supportURL              https://github.com/xlsama/tampermonkey-scripts/issues
// @match                   *://github.com/*
// @include                 *://*github*
// @grant                   none
// @license                 MIT
// ==/UserScript==

// 判断当前path是否是一个 github repo,且位于项目的主页面
function isGithubRepo(path) {
  path = path.slice(0, -1)
  return path.split('/').length === 3
}

// 创建 package 图标 SVG 的辅助函数
function createPackageIcon() {
  const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
  svg.setAttribute('aria-hidden', 'true')
  svg.setAttribute('focusable', 'false')
  svg.setAttribute('class', 'octicon octicon-package')
  svg.setAttribute('viewBox', '0 0 16 16')
  svg.setAttribute('width', '16')
  svg.setAttribute('height', '16')
  svg.setAttribute('fill', 'currentColor')
  svg.setAttribute('display', 'inline-block')
  svg.setAttribute('overflow', 'visible')
  svg.setAttribute('style', 'vertical-align: text-bottom;')

  const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
  path.setAttribute(
    'd',
    'm8.878.392 5.25 3.045c.54.314.872.89.872 1.514v6.098a1.75 1.75 0 0 1-.872 1.514l-5.25 3.045a1.75 1.75 0 0 1-1.756 0l-5.25-3.045A1.75 1.75 0 0 1 1 11.049V4.951c0-.624.332-1.2.872-1.514L7.122.392a1.75 1.75 0 0 1 1.756 0ZM7.875 1.69l-4.63 2.685L8 7.133l4.755-2.758-4.63-2.685a.248.248 0 0 0-.25 0ZM2.5 4.775v5.913c0 .09.047.171.125.216l4.625 2.683V7.653Zm6.25 8.832 4.625-2.683a.25.25 0 0 0 .125-.216V4.775L8.75 7.653Z'
  )

  svg.appendChild(path)
  return svg
}

// 创建 releases 按钮(带文本)
function createReleasesButton() {
  const el = document.querySelector('[class^="OverviewContent-module__Box_4"]')

  if (!el) {
    return
  }

  // 检查是否已经存在 releases 按钮
  if (el.querySelector('a[href*="/releases"]')) {
    return
  }

  // 创建按钮链接
  const a = document.createElement('a')
  a.type = 'button'
  a.href = `${window.location.pathname}/releases`
  a.className = 'prc-Button-ButtonBase-c50BI OverviewContent-module__Button--MDoYP'
  a.setAttribute('data-loading', 'false')
  a.setAttribute('data-size', 'medium')
  a.setAttribute('data-variant', 'invisible')

  // 创建按钮内容容器
  const buttonContent = document.createElement('span')
  buttonContent.setAttribute('data-component', 'buttonContent')
  buttonContent.setAttribute('data-align', 'center')
  buttonContent.className = 'prc-Button-ButtonContent-HKbr-'

  // 创建图标容器
  const visualWrap = document.createElement('span')
  visualWrap.setAttribute('data-component', 'leadingVisual')
  visualWrap.className = 'prc-Button-Visual-2epfX prc-Button-VisualWrap-Db-eB'

  const svg = createPackageIcon()
  visualWrap.appendChild(svg)

  // 创建文本标签
  const label = document.createElement('span')
  label.setAttribute('data-component', 'text')
  label.className = 'prc-Button-Label-pTQ3x'
  label.textContent = 'Releases'

  // 组装按钮
  buttonContent.appendChild(visualWrap)
  buttonContent.appendChild(label)
  a.appendChild(buttonContent)

  // 添加到容器
  el.appendChild(a)
}

// 创建 releases 按钮(仅图标)
function createReleasesButtonMobile() {
  const el = document.querySelector('[class^="OverviewContent-module__Box_5"]')

  if (!el) {
    return
  }

  // 检查是否已经存在 releases 按钮
  if (el.querySelector('a[href*="/releases"]')) {
    return
  }

  // 创建按钮链接
  const a = document.createElement('a')
  a.type = 'button'
  a.href = `${window.location.pathname}/releases`
  a.setAttribute('aria-label', 'Go to Releases page')
  a.className = 'prc-Button-ButtonBase-c50BI OverviewContent-module__Button_1--_1Ng2'
  a.setAttribute('data-loading', 'false')
  a.setAttribute('data-no-visuals', 'true')
  a.setAttribute('data-size', 'medium')
  a.setAttribute('data-variant', 'invisible')

  const svg = createPackageIcon()
  a.appendChild(svg)

  // 添加到容器
  el.appendChild(a)
}

function initButtons() {
  if (!isGithubRepo(window.location.pathname)) {
    return
  }

  createReleasesButton()
  createReleasesButtonMobile()
}

;(function () {
  'use strict'

  // 初始化
  initButtons()

  // 监听页面变化
  new MutationObserver(() => {
    // 检查两个容器是否存在
    if (
      document.querySelector('[class^="OverviewContent-module__Box_4"]') ||
      document.querySelector('[class^="OverviewContent-module__Box_5"]')
    ) {
      initButtons()
    }
  }).observe(document, {
    childList: true,
    subtree: true,
  })
})()