Github => Graphite button

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

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