GitHub Sourcegraph Button

An userscript to add "Sourcegraph" button on github.

  1. // ==UserScript==
  2. // @name GitHub Sourcegraph Button
  3. // @namespace yikai.info
  4. // @version 1.0.1
  5. // @description An userscript to add "Sourcegraph" button on github.
  6. // @author martianyi
  7. // @match https://github.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13. var rawUrl = '';
  14.  
  15. function replace(){
  16. var rawBtn = document.querySelector('#raw-url');
  17. if(rawBtn && rawUrl !== rawBtn.href){
  18. rawUrl = rawBtn.href;
  19. createButton(rawBtn);
  20. }
  21. }
  22.  
  23. function createButton(btn) {
  24.  
  25. var newBtn = btn.cloneNode(false);
  26. newBtn.removeAttribute("id");
  27. newBtn.setAttribute('class', 'btn btn-sm BtnGroup-item');
  28. newBtn.textContent = "Sourcegraph";
  29. newBtn.href = "";
  30. newBtn.addEventListener('click', goToSourcegraph);
  31.  
  32. btn.parentNode.insertBefore(newBtn, btn.nextSibling);
  33.  
  34. if (!btn.parentNode.classList.contains("btn-group")) {
  35. var parent = btn.parentNode,
  36. group = document.createElement("div");
  37. group.className = "btn-group";
  38. while (parent.childNodes.length) {
  39. group.appendChild(parent.childNodes[0]);
  40. }
  41. parent.appendChild(group);
  42. }
  43. }
  44.  
  45. function goToSourcegraph(event) {
  46. event.preventDefault();
  47. var pats = [
  48. ['^/([^/]+)/([^/]+)/tree/([^/]+)$', '/github.com/$1/$2@$3', '^/github.com/([^/]+)/([^/@]+)@([^/]+)$', '/$1/$2/tree/$3'],
  49. ['^/([^/]+)/([^/]+)/tree/([^/]+)/(.+)$', '/github.com/$1/$2@$3/-/tree/$4', '^/github.com/([^/]+)/([^/@]+)@([^/]+)/-/tree/(.+)$', '/$1/$2/tree/$3/$4'],
  50. ['^/([^/]+)/([^/]+)/blob/([^/]+)/(.+)$', '/github.com/$1/$2@$3/-/blob/$4', '', ''],
  51. ['^/([^/]+)/([^/]+)$', '/github.com/$1/$2', '^/github.com/([^/]+)/([^/]+)$', '/$1/$2'],
  52. ['^/([^/]+)$', '/$1', '^/([^/]+)$', '/$1'],
  53. ];
  54. var pathname = window.location.pathname;
  55. for (var i = 0; i < pats.length; i++) {
  56. var pat = pats[i];
  57. var r,
  58. pathname2;
  59. if (window.location.hostname === 'github.com') {
  60. if (pat[0] === '') {continue;}
  61. r = new RegExp(pat[0]);
  62. if (pathname.match(r)) {
  63. pathname2 = pathname.replace(r, pat[1]);
  64. window.location = 'https://sourcegraph.com' + pathname2;
  65. return;
  66. }
  67. } else {
  68. if (pat[2] === '') { continue; }
  69. r = new RegExp(pat[2]);
  70. if (pathname.match(r)) {
  71. pathname2 = pathname.replace(r, pat[3]);
  72. window.location = 'https://github.com' + pathname2;
  73. return;
  74. }
  75. }
  76. }
  77. alert('Unable to jump to Sourcegraph (no matching URL pattern).');
  78. }
  79.  
  80. var container =
  81. document.querySelector("#js-repo-pjax-container") ||
  82. document.querySelector("#js-pjax-container");
  83.  
  84. if (container) {
  85. new MutationObserver(function(){
  86. replace();
  87. }).observe(container, {childList: true, subtree: true});
  88. }
  89.  
  90. replace();
  91. })();