GitHub: sort by recently updated

Adds 2 links to sort by "recently updated" (issues & PR)

  1. // ==UserScript==
  2. // @name GitHub: sort by recently updated
  3. // @namespace https://github.com/Procyon-b
  4. // @version 0.5.6
  5. // @description Adds 2 links to sort by "recently updated" (issues & PR)
  6. // @author Achernar
  7. // @match https://github.com/*
  8. // @run-at document-end
  9. // @grant none
  10. // @noframes
  11. // ==/UserScript==
  12.  
  13. (function() {
  14.  
  15. 'use strict';
  16. var E;
  17. getE();
  18. if (!E) return;
  19.  
  20. var TO, obs=new MutationObserver(cb), config = { attributes: false, childList: true, subtree: false};
  21. obs.observe(E, config);
  22.  
  23. function cb(mutL,o) {
  24. for(var mut of mutL) {
  25. if (mut.type == 'childList') {
  26. if (TO) clearTimeout(TO);
  27. TO=setTimeout(addLink,0);
  28. }
  29. }
  30. }
  31.  
  32. function getE() {
  33. if (!E || !E.offsetParent) {
  34. E=document.getElementById("js-repo-pjax-container") || document.querySelector('.application-main main');
  35. }
  36. return E;
  37. }
  38.  
  39. new MutationObserver(function(){
  40. if (TO) clearTimeout(TO);
  41. TO=setTimeout(addLink,0);
  42. }).observe(document.body, { attributes: false, childList: true, subtree: false });
  43.  
  44. function addLink() {
  45. var e=getE().querySelector('nav.js-repo-nav, nav'), user;
  46.  
  47. function aLink(e,q,st,st0) {
  48. if (!e) return;
  49. if (e.id) return;
  50. var astyle=((st0!=undefined) && st0) || '', style='', url=e.href || e.parentNode.href, Q=url.indexOf('?')>=0;
  51. url+=(Q?'':'?q=')+(q?'+'+escape(q):'')+(Q?'':'+is%3Aopen')+'+sort%3Aupdated-desc';
  52. if ((url == location.href)) style+=( ((st!=undefined) && st) || 'background-color:#EEEEEE;');
  53. e.innerHTML+='<a style="color:inherit; text-decoration:inherit; position:relative;'+astyle+'" href="'+url+'"> <span'+(style?' style="'+style+'"':'')+'>(r)</span> </a>';
  54. e.id="addedModifiedLink";
  55. }
  56.  
  57. user=document.head.querySelector(':scope meta[name="user-login"]');
  58. if (e) {
  59. aLink(e.querySelector(':scope span a[data-selected-links~="repo_issues"] span[itemprop="name"], :scope li a[data-selected-links~="repo_issues"] span[itemprop="name"], :scope li a[data-selected-links~="repo_issues"] span[data-content]'),'is:issue');
  60. aLink(e.querySelector(':scope span a[data-selected-links~="repo_pulls"] span[itemprop="name"], :scope li a[data-selected-links~="repo_pulls"] span[itemprop="name"], :scope li a[data-selected-links~="repo_pulls"] span[data-content]'),'is:pr');
  61. let aria=e.attributes['aria-label'], c, RE;
  62. if (aria && ['Issues','Pull Requests'].includes(aria.value) ) {
  63. if (!e.id) {
  64. RE=new RegExp('\\+(author|assignee|mentions)%3A'+user.content);
  65. e.id='addedCommenter';
  66. c=e.firstElementChild.cloneNode(true);
  67. c.innerText='Commenter';
  68. c.title=aria.value+' you commented';
  69. c.attributes['aria-label'].value=aria.value+' you commented';
  70. c.removeAttribute('aria-current');
  71. c.id='commenter';
  72. let u=c.href.replace(RE,'+commenter%3A'+user.content);
  73. if (u.startsWith(location.origin)) u=u.substr(location.origin.length);
  74. c.href=u;
  75. c.dataset.selectedLinks='dashboard_commented '+u;
  76. c.classList.remove('selected');
  77. e.appendChild(c);
  78. setTimeout(addLink,0);
  79. if (aria.value=='Pull Requests') {
  80. let s=document.createElement('style');
  81. s.textContent='.subnav-search-input-wide {width: 450px;}';
  82. c.appendChild(s);
  83. }
  84. }
  85. else {
  86. let cmt='+commenter%3A'+user.content, sel=e.getElementsByClassName('selected');
  87. RE=new RegExp('\\+commenter%3A'+user.content,'g');
  88. for (let c,i=0; c=e.children[i]; i++) {
  89. if (!c.href) continue;
  90. if ( (c.id=='commenter') && !sel.length) c.classList.add('selected');
  91. let u=c.href.replace(RE, '');
  92. if (u.startsWith(location.origin)) u=u.substr(location.origin.length);
  93. c.href=u+(c.id=='commenter'?cmt:'');
  94. c.dataset.selectedLinks=c.dataset.selectedLinks.replace(RE, '')+(c.id=='commenter'?cmt:'');
  95. }
  96. }
  97. }
  98. }
  99. if (user) {
  100. aLink(document.querySelector('nav[aria-label="Global"] a[href="/pulls"]'), 'is:open+is:pr+author:'+user.content+'+archived:false', ' ','font-size:0.8em;');
  101. aLink(document.querySelector('nav[aria-label="Global"] a[href="/issues"]'), 'is:open+is:issue+author:'+user.content+'+archived:false', ' ','font-size:0.8em;');
  102. }
  103. }
  104.  
  105. addLink();
  106.  
  107. })();