GitHub Issue 左侧悬浮列表添加编号

将 GitHub 的 issue 列表页面转换为一个悬浮在网页左侧,点击标题后在右侧打开具体页面,并为左侧列表中的每一项添加编号并高亮显示

  1. // ==UserScript==
  2. // @name GitHub Issue 左侧悬浮列表添加编号
  3. // @namespace http://your.namespace.com
  4. // @version 1.0
  5. // @description 将 GitHub 的 issue 列表页面转换为一个悬浮在网页左侧,点击标题后在右侧打开具体页面,并为左侧列表中的每一项添加编号并高亮显示
  6. // @match https://github.com/*/issues*
  7. // @grant GM_addStyle
  8. // ==/UserScript==
  9.  
  10. (function() {
  11. 'use strict';
  12.  
  13. var sidebar = document.createElement('div');
  14. sidebar.id = 'issue-sidebar';
  15. document.body.appendChild(sidebar);
  16.  
  17. var currentPage = 1;
  18. var totalIssues = 0;
  19.  
  20. var loadButton = document.createElement('button');
  21. loadButton.textContent = '加载更多';
  22. loadButton.className = 'load-more-button';
  23. sidebar.appendChild(loadButton);
  24.  
  25. loadButton.addEventListener('click', function() {
  26. loadIssues();
  27. });
  28.  
  29. loadIssues();
  30.  
  31. function loadIssues() {
  32. loadButton.disabled = true;
  33. loadButton.textContent = '加载中...';
  34.  
  35. var url = `https://github.com${window.location.pathname}?page=${currentPage}&q=is%3Aissue`;
  36. fetch(url)
  37. .then(function(response) {
  38. return response.text();
  39. })
  40. .then(function(html) {
  41. var parser = new DOMParser();
  42. var doc = parser.parseFromString(html, 'text/html');
  43. var issueLinks = doc.querySelectorAll('.js-navigation-open');
  44.  
  45. issueLinks.forEach(function(link) {
  46. var title = link.innerText;
  47. var url = link.href;
  48. var issueNumber = ++totalIssues;
  49.  
  50. var listItem = document.createElement('div');
  51. listItem.className = 'issue-list-item';
  52. listItem.innerHTML = `<span class="issue-number">${issueNumber}</span> ${title}`;
  53.  
  54. listItem.addEventListener('click', function(event) {
  55. event.preventDefault();
  56. openIssueInRightPane(url);
  57. });
  58.  
  59. sidebar.insertBefore(listItem, loadButton);
  60. });
  61.  
  62. currentPage++;
  63. loadButton.disabled = false;
  64. loadButton.textContent = '加载更多';
  65. })
  66. .catch(function(error) {
  67. console.error('Failed to load issues:', error);
  68. loadButton.disabled = false;
  69. loadButton.textContent = '加载更多';
  70. });
  71. }
  72.  
  73. GM_addStyle(`
  74. #issue-sidebar {
  75. position: fixed;
  76. top: 0;
  77. left: 0;
  78. height: 100vh;
  79. width: 200px;
  80. background-color: #f5f5f5;
  81. overflow-y: scroll;
  82. padding: 10px;
  83. z-index: 9999;
  84. }
  85.  
  86. .issue-list-item {
  87. cursor: pointer;
  88. margin-bottom: 10px;
  89. }
  90.  
  91. .issue-number {
  92. display: inline-block;
  93. padding: 2px 6px;
  94. background-color: #0366d6;
  95. color: #fff;
  96. font-weight: bold;
  97. margin-right: 5px;
  98. border-radius: 4px;
  99. }
  100.  
  101. .load-more-button {
  102. margin-top: 10px;
  103. }
  104.  
  105. #issue-right-pane {
  106. position: fixed;
  107. top: 0;
  108. left: 220px;
  109. right: 0;
  110. bottom: 0;
  111. padding: 10px;
  112. background-color: #fff;
  113. z-index: 9998;
  114. overflow-y: scroll;
  115. border-left: 1px solid #e1e4e8;
  116. }
  117. `);
  118.  
  119. function openIssueInRightPane(url) {
  120. var rightPane = document.getElementById('issue-right-pane');
  121. if (!rightPane) {
  122. rightPane = document.createElement('div');
  123. rightPane.id = 'issue-right-pane';
  124. document.body.appendChild(rightPane);
  125. } else {
  126. rightPane.innerHTML = '';
  127. }
  128.  
  129. fetch(url)
  130. .then(function(response) {
  131. return response.text();
  132. })
  133. .then(function(html) {
  134. rightPane.innerHTML = html;
  135. })
  136. .catch(function(error) {
  137. console.error('Failed to load issue:', error);
  138. });
  139. }
  140. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址