Add filename copy button to the Github PR review comments

What the title says

  1. // ==UserScript==
  2. // @name Add filename copy button to the Github PR review comments
  3. // @description What the title says
  4. // @namespace ahappyviking
  5. // @version 2
  6. // @grant none
  7. // @match https://github.com/*
  8. // @require https://unpkg.com/bundled-github-url-detector@1.0.0/index.js
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12.  
  13. const gh = githubUrlDetection
  14.  
  15. const addButtons = () => {
  16. if (!gh.isPRConversation()) return
  17. const commentFrames = document.querySelectorAll("turbo-frame[id^=review-thread-or-comment-id]")
  18. commentFrames.forEach(frame => {
  19. const parent = frame.querySelector("details")
  20. if (!parent) return
  21. const link = parent.querySelector("a")
  22. if (!link) return
  23.  
  24. const button = generateButton(link.textContent, link.offsetWidth)
  25. parent.style.position = "relative"
  26. parent.appendChild(button)
  27. })
  28. }
  29.  
  30. const generateButton = (url, leftOffset) => {
  31. //Taken from Github source...
  32. const htmlStr = `<clipboard-copy data-copy-feedback="Copied!" aria-label="Copy" value="${url}" data-view-component="true" class="Link--onHover color-fg-muted ml-2 mr-2" tabindex="0" role="button">
  33. <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy">
  34. <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
  35. </svg>
  36. <svg style="display: none;" aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check color-fg-success">
  37. <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
  38. </svg>
  39. </clipboard-copy>`
  40.  
  41. const template = document.createElement('template');
  42. template.innerHTML = htmlStr;
  43. const button = template.content.firstElementChild
  44. button.style.position = "absolute"
  45. button.style.top = "8px"
  46. button.style.left = `${leftOffset + 40}px`
  47. return button
  48. }
  49.  
  50. addButtons()
  51. document.addEventListener("soft-nav:end", addButtons);
  52. document.addEventListener("navigation:end", addButtons);

QingJ © 2025

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