Greasy Fork 还支持 简体中文。

GitHub Sortable Filelist

appends sorting function to github directories

目前為 2014-11-11 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name GitHub Sortable Filelist
  3. // @namespace trespassersW
  4. // @description appends sorting function to github directories
  5. // @include https://github.com/*
  6. // @version 14.11.11.4
  7. // .4 now works on all github pages
  8. // @created 2014-11-10
  9. // @updated 2014-11-11
  10. // @author trespassersW
  11. // @licence MIT
  12. // @run-at document-end
  13. // @grant GM_none
  14. // ==/UserScript==
  15.  
  16. if(document.body && document.querySelector('#js-repo-pjax-container')){ // .file-wrap
  17.  
  18. (function(){ "use strict";
  19. var llii=0; function _l(m){ if(0) console.log(++llii +': '+m) }
  20.  
  21. function stickStyle(css){
  22. var s=document.createElement("style"); s.type="text/css";
  23. s.appendChild(document.createTextNode(css));
  24. return (document.head||document.documentElement).appendChild(s);
  25. }
  26. function insBefore(n,e){
  27. return e.parentNode.insertBefore(n,e);
  28. }
  29. function insAfter(n,e){
  30. if(e.nextElementSibling)
  31. return e.parentNode.insertBefore(n,e.nextElementSibling);
  32. return e.parentNode.appendChild(n);
  33. }
  34. function outerNode(target, node) {
  35. if (target.nodeName==node) return target;
  36. if (target.parentNode)
  37. while (target = target.parentNode) try{
  38. if (target.nodeName==node)
  39. return target;
  40. }catch(e){};
  41. return null;
  42. }
  43.  
  44. function css(){
  45. stickStyle('\
  46. .fsort-butt, .tables.file {position: relative; }\
  47. .fsort-butt:before{\
  48. position: absolute; left:1.5em; top: -1em; \
  49. cursor: pointer;\
  50. content: "";\
  51. z-index:99999;\
  52. width: 0; height: 0;\
  53. opacity:.2;\
  54. }\
  55. .fsort-asc:before,\
  56. .fsort-desc.fsort-sel:hover:before\
  57. {\
  58. border-left: 6px solid transparent;\
  59. border-right: 6px solid transparent;\
  60. border-bottom: 14px solid #444;\
  61. border-top: 0;\
  62. }\
  63. .fsort-desc:before,\
  64. .fsort-asc.fsort-sel:hover:before{\
  65. border-left: 6px solid transparent;\
  66. border-right: 6px solid transparent;\
  67. border-bottom: 0;\
  68. border-top: 14px solid #444;\
  69. }\
  70. .fsort-butt.fsort-desc.fsort-sel:hover:before,\
  71. .fsort-butt.fsort-asc.fsort-sel:before{\
  72. border-bottom: 14px solid #4183C4;\
  73. border-top: 0;\
  74. }\
  75. .fsort-butt.fsort-desc.fsort-sel:before,\
  76. .fsort-butt.fsort-asc.fsort-sel:hover:before{\
  77. border-bottom: 0;\
  78. border-top: 14px solid #4183C4;\
  79. }\
  80. \
  81. .fsort-butt.fsort-sel:before{ opacity: .6 }\
  82. .fsort-butt:hover:before{ opacity: 1 !important;}\
  83. /* patches */\
  84. table.files td.age {text-align: left !important;}\
  85. table.files td.message {overflow-y: visible !important;}\
  86. ');//#80A6CD
  87. }
  88. var ii=0;
  89. var d0=[0,0,1];
  90. var C=[{c:1, d: 0, s: 0},{c:2, d: 0, s: 0},{c:3, d: 1, s: 0}];
  91. var ASC;
  92. var oa=[],ca=[];
  93. var D=document, TB;
  94. var catcher;
  95. function setC(n){
  96. for(var i=0,il=C.length; i<il; i++ ){
  97. if(i!=n) C[i].s= 0, C[i].d=d0[i];
  98. else C[i].s=1;
  99. oa[i].className='fsort-butt fsort-'+(C[i].d?'desc':'asc')+(C[i].s?' fsort-sel':'') ;
  100. oa[i].title=C[i].d? '\u21ca' : '\u21c8';
  101. }
  102. }
  103.  
  104. function isDir(x){
  105. return (TB.rows[x].cells[0].querySelector("span.octicon-file-directory")) != null;
  106. }
  107.  
  108. var sDir,sCells;
  109. var fa=[
  110. function(a){
  111. sCells.push(TB.rows[a].cells[1].querySelector('span.css-truncate-target a').textContent);
  112. },
  113. function(a){
  114. sCells.push(TB.rows[a].cells[2].querySelector('span.css-truncate').textContent);
  115. },
  116. function(a){
  117. sCells.push(TB.rows[a].cells[3].querySelector('span.css-truncate>time').getAttribute('datetime'));
  118. }
  119. ]
  120. function sort_p(n){// prepare data for sorting
  121. sDir=[],sCells=[];
  122. for(var tl=TB.rows.length, a=0; a<tl; a++){
  123. sDir.push(isDir(a));
  124. fa[n](a);
  125. }
  126. }
  127.  
  128. function sort_fn(a,b){
  129. var x=sDir[a], y=sDir[b];
  130. if(x!=y) return ((x<y)<<1)-1;
  131. x= sCells[a], y= sCells[b];
  132. return x==y? 0: (((x>y)^ASC)<<1)-1;
  133. }
  134. var CNn={content: 0, message: 1, age: 2}
  135.  
  136. function oClr(){
  137. var o= catcher.querySelectorAll('.fsort-butt')
  138. for(var ol=o.length,i=0;i<ol;i++)
  139. o[i].parentNode.removeChild(o[i]);
  140. }
  141. //
  142. function doSort(t){
  143. TB=outerNode(t,'TBODY');
  144. var tb=[],ix=[], i, tl;
  145. if(!TB) throw "*GHSFL* TBODY not found";
  146. var n=CNn[t.parentNode.className];
  147. if(typeof n=="undefined") throw "*GHSFL* undefined col";
  148. _l('n:'+n);
  149. tl=TB.rows.length;
  150. ASC=C[n].d^=C[n].s;
  151. for( i=0; i<tl; i++)
  152. ix.push(i);
  153. oClr();
  154. sort_p(n);
  155. ix.sort(sort_fn);
  156. for( i=0; i<tl; i++)
  157. tb.push(TB.rows[ix[i]].innerHTML);
  158. for( i=0; i<tl; i++)
  159. TB.rows[i].innerHTML=tb[i];
  160. setC(n);
  161. gitDir1(0);
  162. }
  163.  
  164. function onClik(e){doSort(e.target)}
  165.  
  166. function gitDir1(x){
  167. if(x && document.querySelector('.fsort-butt')) {
  168. _l('gitDir'+x+' - already'); return;
  169. }
  170. _l('gitDir'+x)
  171. var c,o;
  172. ca=[];
  173. c= D.querySelector('.file-wrap table.files td.content >span');
  174. if(!c) throw '*GHSFL* no content';
  175. ca.push(c);
  176. c=D.querySelector('.file-wrap table.files td.message >span');
  177. if(!c) throw '*GHSFL* no messages';
  178. ca.push(c);
  179. c=D.querySelector('.file-wrap table.files td.age >span');
  180. if(!c) throw '*GHSFL* no ages';
  181. ca.push(c);
  182. if(x){ oClr(); oa=[];
  183. o=D.createElement('span');
  184. o.textContent='';
  185. oa.push(o);
  186. o=o.cloneNode(true);
  187. oa.push(o);
  188. o=o.cloneNode(true);
  189. oa.push(o);
  190. setC(-1);
  191. }
  192. insBefore(oa[0],ca[0]);
  193. insBefore(oa[1],ca[1]);
  194. insBefore(oa[2],ca[2]);
  195. }
  196.  
  197. function gitDir(){
  198. gitDir1(1);
  199. }
  200.  
  201. catcher= D.querySelector('#js-repo-pjax-container');
  202. if(!catcher) throw "*GHSFL* err0r";
  203.  
  204. catcher.addEventListener('mousedown',function(e){
  205. if(e.target.nodeName && e.target.nodeName=='SPAN' &&
  206. e.target.className.indexOf('fsort-butt')>-1)
  207. { onClik(e); }
  208. }
  209. ,false);
  210. _l('startup()');
  211. css();
  212. gitDir();
  213. window.GH_SFL=C;
  214. var target = catcher; //document.body; //D.querSelector('.file-wrap');
  215. var MO = window.MutationObserver;
  216. if(!MO) MO= window.WebKitMutationObserver;
  217. if(!MO) return;
  218. var observer = new MO(function(mutations) {
  219. mutations.forEach(function(m) {
  220. if( m.type= "attributes" &&
  221. m.target.nodeName == 'DIV' &&
  222. m.target.className == "file-wrap" )
  223. gitDir();
  224. });
  225. });
  226. observer.observe(D.body, { attributes: true, subtree: true } );
  227. /* attributes: true , childList: true, subtree: true,
  228. characterData: true, attributeOldValue:true, characterDataOldValue:true
  229. */
  230.  
  231. })()};
  232.  
  233. /*
  234. to do: persistent settings; sorting by file extensions; toggling date/time display mode
  235. ... do we really need it?
  236. */