GitHub Project Copy Column

Grab links from a GitHub project column and copy them to the clipboard for easy pasting into a PR or issue description.

As of 2023-08-11. See the latest version.

  1. // ==UserScript==
  2. // @name GitHub Project Copy Column
  3. // @namespace https://github.com/scruffian/github-project-copy-column
  4. // @version 0.1
  5. // @description Grab links from a GitHub project column and copy them to the clipboard for easy pasting into a PR or issue description.
  6. // @author Scruffian
  7. // @match https://github.com/*
  8. // @icon https://raw.githubusercontent.com/xthexder/wide-github/master/icons/icon.png
  9. // @grant none
  10. // @license GPLv2 or later
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. "use strict";
  15. const copyToClipboardHelper = (textToCopy) => {
  16. let finalText = textToCopy;
  17.  
  18. if (textToCopy.current) {
  19. const parentElement = textToCopy.current.parentElement;
  20. const savedDisplay = parentElement.style.display;
  21. parentElement.style.display = "block";
  22. finalText = textToCopy.current.innerText.replace(/([0-9]+)/g, "\r\n$1. ");
  23. parentElement.style.display = savedDisplay;
  24. }
  25.  
  26. const textarea = document.createElement("textarea");
  27. textarea.value = finalText;
  28. document.body.appendChild(textarea);
  29. textarea.select();
  30. document.execCommand("copy");
  31. textarea.remove();
  32. };
  33.  
  34. const columns = document.querySelectorAll("div[data-board-column]");
  35. columns.forEach(function (column) {
  36. const titleDiv = column.querySelector("div > div");
  37. const number = column.querySelector(
  38. "div > div [data-testid=column-items-counter]"
  39. );
  40. let link = document.createElement("span");
  41.  
  42. number.title = "Copy URLs of all cards";
  43. number.onclick = function () {
  44. const scrollableArea = column.querySelector(".column-drop-zone");
  45. scrollableArea.scrollTop = 0;
  46. const allLinks = [];
  47.  
  48. const getLinks = setInterval(function () {
  49. if (
  50. scrollableArea.scrollTop + scrollableArea.offsetHeight + 1 >=
  51. scrollableArea.scrollHeight
  52. ) {
  53. clearInterval(getLinks);
  54. const uniqueLinks = new Set(allLinks);
  55. const linksString = Array.from(uniqueLinks).join("\n\n");
  56. copyToClipboardHelper(linksString);
  57. alert("Copied " + uniqueLinks.size + " links to clipbard");
  58. }
  59. scrollableArea.scrollTop =
  60. scrollableArea.scrollTop + scrollableArea.offsetHeight;
  61. const linksForScrollPoint = column.querySelectorAll(
  62. "[data-testid=board-view-column-card] a"
  63. );
  64. linksForScrollPoint.forEach(function (link) {
  65. if (link.href) {
  66. allLinks.push(link.href);
  67. }
  68. });
  69. }, 150);
  70. };
  71. });
  72. })();