自动填写 GitHub 仓库名简化删除操作

在“删除此存储库”按钮上方添加一个按钮,并在 GitHub 上删除存储库时自动填写存储库名称。

当前为 2024-01-25 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Auto Fill Repository Name when Deletion Confirmation
  3. // @name:zh-CN 自动填写 GitHub 仓库名简化删除操作
  4. // @namespace https://github.com/chiperman/GHRepoDeleteHelper
  5. // @version 1.1
  6. // @description Add a button above the "Delete this repository" button and auto-fill the repository name when deleting a repository on GitHub.
  7. // @description:zh-CN 在“删除此存储库”按钮上方添加一个按钮,并在 GitHub 上删除存储库时自动填写存储库名称。
  8. // @author chiperman
  9. // @match https://github.com/*
  10. // @grant none
  11. // @icon https://github.githubassets.com/pinned-octocat.svg
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17.  
  18. let observer;
  19.  
  20. const createAutoInputButton = () => {
  21. const button = document.createElement('span');
  22. button.innerText = '🤖 Auto Fill';
  23. button.id = 'auto-input-btn';
  24. button.className =
  25. 'js-repo-delete-proceed-button Button--danger Button--medium Button Button--fullWidth';
  26. button.style.display = 'flex';
  27. button.style.justifyContent = 'center';
  28. button.style.alignItems = 'center';
  29. button.style.marginBottom = '8px';
  30. return button;
  31. };
  32.  
  33. const addButtonToContainer = (autoInputBtn, targetButton) => {
  34. const buttonContainer = targetButton.parentElement;
  35. buttonContainer.insertBefore(autoInputBtn, targetButton);
  36. };
  37.  
  38. // Simulate manually typing each character of the repository name into the input block
  39. const simulateInput = (inputBlock, repositoryName) => {
  40. inputBlock.focus();
  41. for (let i = 0; i < repositoryName.length; i++) {
  42. inputBlock.value += repositoryName[i];
  43.  
  44. // Trigger the input event
  45. const inputEvent = new Event('input');
  46. inputBlock.dispatchEvent(inputEvent);
  47. }
  48. };
  49.  
  50. const checkURL = () => {
  51. const currentURL = window.location.href;
  52.  
  53. if (currentURL.match(/^https:\/\/github\.com\/.*\/.*\/settings/)) {
  54. const deleteMenuButton = document.getElementById('dialog-show-repo-delete-menu-dialog');
  55.  
  56. if (deleteMenuButton) {
  57. deleteMenuButton.addEventListener('click', clickDeleteRepositoryBtn);
  58. }
  59. }
  60. };
  61.  
  62. const clickDeleteRepositoryBtn = () => {
  63. const targetNode = document.getElementById('repo-delete-menu-dialog');
  64. observer = new MutationObserver(() => handleDialogClick());
  65. const config = { childList: true, subtree: true };
  66. observer.observe(targetNode, config);
  67. };
  68.  
  69. const handleDialogClick = () => {
  70. const buttonElement = document.getElementById('repo-delete-proceed-button');
  71. const buttonLabel = buttonElement.textContent.trim();
  72.  
  73. if (buttonLabel === 'Delete this repository') {
  74. const autoInputBtn = createAutoInputButton();
  75. addButtonToContainer(autoInputBtn, buttonElement);
  76. autoInputBtn.addEventListener('click', autoInputFunction);
  77. observer.disconnect();
  78. }
  79. };
  80.  
  81. const autoInputFunction = () => {
  82. const repositoryElement = document.querySelector('.text-bold.f3.mt-2');
  83. const repositoryName = repositoryElement.textContent.trim();
  84. const inputBlock = document.getElementById('verification_field');
  85. simulateInput(inputBlock, repositoryName);
  86. };
  87.  
  88. checkURL();
  89. const observerConfig = { childList: true, subtree: true };
  90. const mainObserver = new MutationObserver(() => checkURL());
  91. mainObserver.observe(document.body, observerConfig);
  92. })();