Graphite GitHub button

Add a button to go from app.graphite.dev to github.com

  1. // ==UserScript==
  2. // @name Graphite GitHub button
  3. // @description Add a button to go from app.graphite.dev to github.com
  4. // @match https://app.graphite.dev/*
  5. // @version 0.3
  6. // @run-at document-start
  7. // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
  8. // @grant none
  9. // @license MIT
  10. // @namespace https://app.graphite.dev
  11. // ==/UserScript==
  12.  
  13. const PATH_REGEX = /^\/github\/pr\/(\w+)\/(\w+)\/(\d+).*$/;
  14. const SELECTOR =
  15. '[class^="PullRequestTitleBar_container_"] > div:nth-child(1) > div:nth-child(2)';
  16.  
  17. const addButton = (toolbar) => {
  18. const [_, org, repo, pr] = window.location.pathname.match(PATH_REGEX);
  19. const gitHubLink = `https://github.com/${org}/${repo}/pull/${pr}`;
  20.  
  21. if (document.getElementById("gitHubLink") != null) {
  22. return;
  23. }
  24.  
  25. const anchorEl = document.createElement("a");
  26. anchorEl.setAttribute("id", "gitHubLink");
  27. anchorEl.setAttribute("href", gitHubLink);
  28. anchorEl.setAttribute(
  29. "style",
  30. "background: #f0f0f3; padding: 6px; border-radius: 4px; flex-shrink: 0;"
  31. );
  32. anchorEl.appendChild(document.createTextNode("Open in GitHub"));
  33.  
  34. toolbar.appendChild(anchorEl);
  35. };
  36.  
  37. const toolbarObserver = new MutationObserver((_, observer) => {
  38. const toolbar = document.querySelector(SELECTOR);
  39. if (toolbar) {
  40. observer.disconnect();
  41. addButton(toolbar);
  42. }
  43. });
  44.  
  45. let lastPathname;
  46. const routeChangeObserver = new MutationObserver(() => {
  47. const { pathname } = window.location;
  48.  
  49. if (pathname !== lastPathname) {
  50. lastPathname = pathname;
  51.  
  52. if (pathname.match(PATH_REGEX)) {
  53. toolbarObserver.observe(document.body, {
  54. childList: true,
  55. subtree: true,
  56. });
  57. }
  58. }
  59. });
  60.  
  61. routeChangeObserver.observe(document.body, { childList: true, subtree: true });