GitHub Sortable Filelist

appends sorting function to github directories

Fra og med 19.11.2015. Se den nyeste version.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

  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 15.11.19
  7. // 15.11.19 * fix
  8. // 15.08.12 ++ octicons for file extensions
  9. // 15.08.07 + case-insensitive sorting
  10. // 15.05.07 sorting is now faster
  11. // .12 new age format; fix for chrome
  12. // .10 datetime auto-updating fix; right-aligned datetime column; proper local time; .ext sorting fix;
  13. // .8 sorting by file extention
  14. // .7 date/time display mode switching
  15. // @created 2014-11-10
  16. //
  17. // @author trespassersW
  18. // @license MIT
  19. // @icon https://i.imgur.com/8buFLcs.png
  20. // (C) Icon: Aaron Nichols CC Attribution 3.0 Unported
  21. // @run-at document-end
  22. // @grant unsafeWindow
  23. // ==/UserScript==
  24.  
  25. if(document.body && document.querySelector('#js-repo-pjax-container')){
  26.  
  27. var llii=0, _l= function(){/* * /
  28. for (var s=++llii +':', li=arguments.length, i = 0; i<li; i++)
  29. s+=' ' + arguments[i];
  30. console.log(s)
  31. /* */
  32. }
  33. //_l=console.log.bind(console);
  34. var fakejs = // avoid compiler warning
  35. (function(){ "use strict";
  36.  
  37. var ii=0,tt;
  38. var d0=[0,0,1];
  39. var C=[{c:1, d: 0, s: 0},{c:2, d: 0, s: 0},{c:3, d: 1, s: 0}];
  40. var ASC;
  41. var oa=[],ca=[],clock,ext,dtStyle,upc;
  42. var D=document, TB;
  43. var catcher,locStor;
  44. var prefs={dtStyle:0, ext: 0, upc: 1};
  45. var W= unsafeWindow || window;
  46.  
  47. // see: https://octicons.github.com/
  48. var extIcon=[
  49. //0...........1..............2..............3..............4.......
  50. "octoface" ,"zap" ,"list-unordered","paintcan" ,"eye"
  51. //5...........6..............7..............8..............9.......
  52. ,"globe" ,"file-binary" ,"file-zip" ,"file-pdf" ,"megaphone"
  53. //10..........11.............12.............13.............14......
  54. ,"gear" ,"triangle-right","ruby" ,"info" ,"device-camera"
  55. //15..........16.............17.............18.............19......
  56. ,"pencil" ,"terminal" ,"book"
  57. ]
  58. var extList={
  59. md:0,
  60. js:1,jsm:1,
  61. json:2,xml:2,xul:2,rdf:2,yml:2,
  62. css:3,scss:3,less:3,
  63. png:4,bmp:4,gif:4,cur:4,ico:4,svg:4,
  64. htm:5,html:5,php:5,
  65. bin:6,exe:6,dll:6,
  66. zip:7,rar:7,arj:7,
  67. pdf:8,
  68. wav:9,mp3:9,ogg:9,mp4:9,aac:9,
  69. cfg:10,ini:10,
  70. c:11,cpp:11,cc:11,h:11,hpp:11,asm:11,m:11,
  71. rb:12,py:12,
  72. EmptyExt:13,
  73. jpg:14,jpeg:14,
  74. pl:15,java:15,jar:15,cs:15,
  75. sh:16,mak:16,cmd:16,bat:16,
  76. doc:17,rtf:17,djvu:17
  77. }
  78.  
  79. function stickStyle(css){
  80. var s=document.createElement("style"); s.type="text/css";
  81. s.appendChild(document.createTextNode(css));
  82. return (document.head||document.documentElement).appendChild(s);
  83. }
  84. function insBefore(n,e){
  85. return e.parentNode.insertBefore(n,e);
  86. }
  87. function insAfter(n,e){
  88. if(e.nextElementSibling)
  89. return e.parentNode.insertBefore(n,e.nextElementSibling);
  90. return e.parentNode.appendChild(n);
  91. }
  92. function outerNode(target, node) {
  93. if (target.nodeName==node) return target;
  94. if (target.parentNode)
  95. while (target = target.parentNode) try{
  96. if (target.nodeName==node)
  97. return target;
  98. }catch(e){};
  99. return null;
  100. }
  101. function savePrefs(){
  102. if(locStor) locStor.setItem('GHSFL',JSON.stringify(prefs));
  103. }
  104.  
  105. function css(){
  106. stickStyle('\
  107. .fsort-butt,\n\
  108. .tables.file td.content, .tables.file td.message, .tables.file td.age\n\
  109. {position: relative; }\n\
  110. \n\
  111. .fsort-butt:before{\n\
  112. position: absolute; display: inline-block;\n\
  113. cursor: pointer;\n\
  114. text-align:center; vertical-align: top;\n\
  115. width: 18px; height: 14px;\n\
  116. line-height: 14px;\n\
  117. padding:0; margin:0;\n\
  118. border-color: transparent;\n\
  119. border-width: 0;\n\
  120. content: "";\n\
  121. opacity: .2;\n\
  122. z-index: 99;\
  123. }\n\
  124. .fsort-butt.fsort-asc:before,.fsort-butt.fsort-desc:before{\n\
  125. left:1.5em; top: -1em;\n\
  126. }\n\
  127. td.age .fsort-butt.fsort-asc:before, td.age .fsort-butt.fsort-desc:before{\n\
  128. left: 4.5em; \n\
  129. }\n\
  130. .fsort-asc:before,.fsort-desc:before{\n\
  131. background-color: #48C;\n\
  132. }\n\
  133. .fsort-asc:before{\n\
  134. border-radius: 24px 24px 8px 8px;\n\
  135. }\n\
  136. .fsort-desc:before{\n\
  137. border-radius: 8px 8px 24px 24px;\n\
  138. }\n\
  139. .fsort-asc:before,\n\
  140. .fsort-desc.fsort-sel:hover:before\n\
  141. {\n\
  142. content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAMCAYAAABbayygAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqklEQVR42mNgQAIfPnzg//fv3z4g3vjs2TNOBmzg27dv0kAFl/5DAZB95OPHj4Ioin79+qUFlHj0Hw0Axa5+//5dFqzo58+fGkCB9/9xAKDcw69fv0ow/P37twAqAAJLkRQsgLGBapIZQO4ACk798+eP9+/fv21gkkArZYAKYoFy09++fcuL4lZ0hQy4wMAqtIQpBEaAFE6FL1684AL6chcQb1m1ahUTshwAw2kAJAeNI30AAAAASUVORK5CYII=);\n\
  143. }\n\
  144. .fsort-desc:before,\n\
  145. .fsort-asc.fsort-sel:hover:before{content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAMCAYAAABbayygAAAACXBIWXMAAAsTAAALEwEAmpwYAAAApUlEQVR42mNgQAKrVq1i+vfv3xYg3vXixQsuBlzg27dvUv+h4Pfv35Y4FX7//l0GSaHNYFH49u1bXqAvp//9+zcWXeGfP3+8gXJTP378KMgAVJAMkwQKLkBiLwXifyA2UE0Bw9evXyWA/If/cQCg3PufP39qwNwmCxS4ikXRo1+/fmmhuBXkDqDEESRFl4ARII3V18+ePeMEKtgIxPs+fPjAjywHANCcACRZ1c8XAAAAAElFTkSuQmCC);\n\
  146. }\n\
  147. \n\
  148. .fsort-butt.fsort-sel:before\n\
  149. {\n\
  150. background-color: #4183C4 !important;\n\
  151. opacity:.6 !important;\n\
  152. }\n\
  153. \n\
  154. span.fsort-butt:hover:before\n\
  155. ,span.fsort-butt:hover span:before\n\
  156. { opacity: 1 !important;}\n\
  157. \n\
  158. #fsort-clock:before{\n\
  159. left:6.5em; top: -15px; \n\
  160. text-align:center; vertical-align: top; top:-15px;\n\
  161. width: 16px; height: 16px;\
  162. border-radius: 16px;\n\
  163. content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlZJREFUeNqkU0tLG1EUvjORFJPMw6mhTUgxy75EUxiJj6CGLKQV0o2IQd3pxp2bbPs/3MVCIHSRgC3uXBhCSErjtLRkK7TcNCYhk4eGPHvO6AwjXXrgu/fOOff77plzz2VGoxF5iI3hEA6HCcuyxGKxEIZhOMBLcHsAwt0+FfAbDvsFaA4GAzIcDkkqlboVMNlzB8+vzgUCq3N+v+xyOl3opFdXNJfN5nPn52dNVT0DV/FeBjpZcjrfR/b3Dzwul0e02ciPiwsyPTtLptxur7C25n0xMzMfPzoSypQmdREWB0iLt3NcKLK3dzAhSR5+fFxT/JbPG+row9g2HABZhpBjCMA/vZYDgRVOFD02q5WwDKOROp2OIYA+jDlgz8Ly8gpyDIF+v++d9vlkXDdubshlpaKhWCwaawTGsHg+WZaRY9QAPiYEUXyinzY1OanNzWbTWGv7gPynViO4FzlmARavcWgivw2FSDAYJDubm4TjOA0Oh4O8WVwk80tLGscsoLZUtWwThGf6afFEgmxvbZGP8biRAbac2u2S60ajjByjBr1e7/JrJqOMQSNhmmiCJGlknHVAAckjuI1cOq0gx3wLyudkMt1ttejgTkAXMRsWkO106KdEIo0cQwAC9b+l0umHaPRYrVaphWX/63n0XasqjR4eHlNKT5FzrxPBoXxXFEtkY6Ozs7u78G59/dVTt/sxdkSJ0uqXk5OfsVgsU6lUUjzPKzqPwdfo8/lIF4pTr9dJu92WID0/tjZAv8MKti48tqzdbq+JUAsrNFWhULgVeIj9E2AAamUckFr2UCoAAAAASUVORK5CYII=\n\
  164. );}\n\
  165. .fsort-on:before{ background-color: #4183C4 !important; } \n\
  166. #fsort-ext:before{\n\
  167. left:4em; top:-14px;\n\
  168. width:28px; height: 14px;\n\
  169. border-radius: 6px;\n\
  170. content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAANCAYAAAC3mX7tAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAABWUlEQVQ4y+2SP0sDQRDFT7BQTGtnITYSK8Emha1NCrXwC4gWYiUKiiB4jYKdWAmC4AewtxEExSqVjZ1/OEgwrEQwkLvbmd/aTCBI0IBYCD7YYmaYfW/mTRT9VWRZNq6qm79OBBwBrueGPM8ngWvgHbgXkQX7aC+EEFR1x+IDi7dUdQOQYACuviSp1+tDQA2oquoycAlInucT1Wp1EHgA3r3300AG3FUqlX4RKQOvQFNVV0Rk9ksiEZkzRbtJkgx476faqq1etnoK4L0vdazuqefVqepq6ALgKIqiKI7jPuDRcpVPHn1P5JwrxHHc1zHRofe+1H5pmo6akCWrv4QQgojMdxA9AI3vzPfAsXOuACRAXVW3VXUNOM2yrNhsNofNh1qapmPAG5A45wpGdGMiToD9bvdftKZ9I54ALoCGXd5tq9UaAc7Mr0Wbbr09vfk3Azybf+fRP36KDxJ2sN2uMATcAAAAAElFTkSuQmCC);\n\
  171. }\n\
  172. #fsort-ext:before{ background-color: #BBB}\n\
  173. /* 150806 uppercase */\n\
  174. #fsort-upc:before{\n\
  175. left:7em; top:-14px;\n\
  176. width:16px; height: 16px;\n\
  177. border-radius: 0 4px 0 4px;\n\
  178. content:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAABcElEQVQ4y5WSsWoVQRSG/7kbyL1VCosgeQBBbFIYtBCsLYOx1QewiZgqr5HOF5ALRlALbcUigsK1TOUWooUaEbOL2d3z/TaTsOBduPeHYQ4zZ77555yRJEXEDnAE/AZ+As/qur6sBbSS50uS1iQ9lbSZUtoej8eWdHcRiKbT6eg8bprmqm0D37Souq7bBt4BP4AuA04XOtw0zTUggLOIeBgR95YBjIqi2EwpjSTNiqI4sP1dy6ht21v5xjPgCfAZaPoOImLfWRGx/x8EOAD+AF8j4gFw2AcAx8DfPI6XdXgzO3wNvLHttm1vXNRAkmzfGQIURXE/57ywfdhfu5Dt57av59i2b0tSWZarwC+Auq43qqpazx07KctytQ+4Yvuj7c52advnXzzbP+rV420u5s5cy30HwCsPCHgpSWno7VVVrU8mky8ppRXb73tbKaW0Zbur63pjsPoR8Sjf9GFO22f5GbuDAOBTTno8B76X4bN/RgN/lIzFNCAAAAAASUVORK5CYII=);\n\
  179. }\n\
  180. #fsort-upc:before{ background-color: #BBB}\n\
  181. \n\
  182. table.files td.age .css-truncate.css-truncate-target{\n\
  183. width: 99% !important; \n\
  184. max-width: none !important;\n\
  185. }\n\
  186. /*table.files td.age span.css-truncate time{\n\
  187. position: relative !important;\n\
  188. }*/\n\
  189. .fsort-time {\n\
  190. visibility: hidden;\n\
  191. display: none;\n\
  192. padding-right: 0px;\n\
  193. }\n\
  194. .fsort-time i {\n\
  195. display:inline-block;\
  196. color: #BBB;\
  197. font-style: normal !important;\n\
  198. transform: scale(0.9);\n\
  199. margin-left: 0px;\n\
  200. /* font-size: 12px;*/\n\
  201. }\n\
  202. \n\
  203. /* patches (--min-width:12em!important;) */\n\
  204. table.files td.age {text-align: right !important; padding-right: 4px !important;\n\
  205. width:12em!important;\n\
  206. \n\
  207. max-width:none!important;\n\
  208. overflow:visible!important;\n\
  209. }\n\
  210. table.files td.message {overflow: visible !important;}\n\
  211. /*.file-wrap .include-fragment-error { display: table-row !important;}*/\n\
  212. /* 150315 wide filelist *150426 better not touch this* /\n\
  213. div.wrapper div.container{\n\
  214. min-width: 980px!important;\n\
  215. width:90%!important;}\n\
  216. div.wrapper div#js-repo-pjax-container{\n\
  217. min-width: 790px!important;\n\
  218. width: calc(100% - 200px)!important;\n\
  219. }/* */\n\
  220. \
  221. ');
  222.  
  223. dtStyle=stickStyle('\
  224. td.age span.css-truncate time{\
  225. visibility: hidden !important;\
  226. display: none !important;\
  227. }\
  228. td.age span.css-truncate .fsort-time {\
  229. visibility: visible !important;\
  230. display: inline !important;\
  231. }\
  232. ')
  233. }
  234.  
  235. function setC(n){
  236. for(var i=0,il=C.length; i<il; i++ ){
  237. if(i!=n) C[i].s= 0, C[i].d=d0[i];
  238. else C[i].s=1;
  239. oa[i].className='fsort-butt fsort-'+(C[i].d?'desc':'asc')+(C[i].s?' fsort-sel':'') ;
  240. //oa[i].title=C[i].d? '\u21ca' : '\u21c8';
  241. }
  242. }
  243.  
  244. function dd(s)
  245. { s=s.toString(); if(s.length<2)return'0'+s; return s}
  246. function d2s(n){
  247. var hs=dd(n.getHours())+':'+dd(n.getMinutes());
  248. return {
  249. d: n.getFullYear()+'-'+dd(n.getMonth()+1)+'-'+dd(n.getDate())+'<i>'+ hs+'</i>',
  250. t: hs+':'+dd(n.getSeconds())
  251. }
  252. }
  253.  
  254. var xmatch=/(.*)\.(.*)$/;
  255. function filext(x){
  256. var m= x.match(xmatch);
  257. if(!m || !m[2]) return "EmptyExt";
  258. return m[2].toLowerCase();
  259. }
  260. function setIcon(tr){
  261. var xt,tc,ti=tr.querySelector('td.icon > span.octicon-file-text');
  262. if(!ti) return;
  263. tc=tr.querySelector('td.content > span.css-truncate');
  264. if(!tc) return;
  265. tc=tc.textContent;
  266. if(!tc) return;
  267. xt=filext(tc);
  268. if(!xt) return;
  269. xt=extList[xt];
  270. if(typeof xt === "undefined") return;
  271. ti.className='octicon octicon-'+ extIcon[xt];
  272. //_l('setIcon '+xt);
  273. }
  274.  
  275. function setDateTime(x){
  276. var dt,dtm,dta,dtd,tc,m,now,t;
  277. var DT=D.querySelectorAll('td.age span.css-truncate time');
  278. _l('sDT',x?'refresh':'create');
  279. try{
  280. now = new Date();
  281. for(var dl=DT.length, i=0; i<dl; i++){
  282. dta=DT[i].getAttribute('datetime');
  283. dtd=new Date(dta);
  284. dt= d2s(dtd); // 2014-07-24T17:06:11Z
  285. dtm=null;
  286. if(x){
  287. dtm=DT[i].parentNode.querySelector('.fsort-time');
  288. }
  289. if(!dtm){
  290. dtm=D.createElement('span');
  291. dtm.className='fsort-time';
  292. x=0;
  293. }
  294. if(!x || !dtm.title || dtm.title != DT[i].title)
  295. { dtm.title= DT[i].title;
  296. t= dt.d;
  297. if( (now.getTime() - dtd.getTime() < 12*3600*1000) ||
  298. ((now.getTime() - dtd.getTime() < 24*3600*1000) &&
  299. (now.getDate() == dtd.getDate()) )
  300. ) t=dt.t;
  301. dtm.innerHTML=t;
  302. }
  303. if(!x) insAfter(dtm,DT[i]);
  304. if(!x)
  305. setIcon(outerNode(DT[i],'TR'));
  306. }
  307. /* 150810 */
  308. }catch(e){(console.log(e+'\n*GHSFL* wrong datetime'+x))}
  309. }
  310.  
  311. function isDir(x){
  312. var c= TB.rows[x].cells[0].querySelector("span");
  313. if(c.className.indexOf("-directory")>0) return 0;
  314. if(c.className.indexOf("octicon-")>0) return -1;
  315. return 1;
  316. }
  317. function getCell(r,c,s,p){
  318. var rc=TB.rows[r].cells[c],q=null;
  319. if(typeof rc == "undefined") {
  320. _l('r:',r,'c:',c,'- ???' );
  321. }else
  322. q=rc.querySelector(s);
  323. if(q) q= p? q.getAttribute(p): q.textContent;
  324. if(q) return q;
  325. return "";
  326. }
  327. var sDir,sCells,sExts;
  328. var fa=[
  329. function(a){
  330. var r=getCell(a,1,'span.css-truncate-target a');
  331. return prefs.upc? r.toUpperCase(): r;
  332. },
  333. function(a){
  334. var r= getCell(a,2,'span.css-truncate');
  335. r=r.replace(/\s+/,' ').replace(/^\s|\s$/,'');
  336. return prefs.upc? r.toUpperCase(): r;
  337. },
  338. function(a){
  339. var c = getCell(a,3,'span.css-truncate>time','datetime');
  340. if(c) return c;
  341. return "2099-12-31T23:59:59Z"
  342. }
  343. ]
  344.  
  345. var b9='\x20\x20\x20'; b9+=b9+b9;
  346. function pad9(s){
  347. if(s.length<9) return (s+b9).substr(0,9);
  348. return s;
  349. }
  350. function sort_p(n){// prepare data for sorting
  351. sDir=[],sCells=[];
  352. for(var tl=TB.rows.length, a=0; a<tl; a++)
  353. sDir.push(isDir(a));
  354. if( n === 0 && prefs.ext ){
  355. for( a=0; a<tl; a++){ // f.x -> x.f
  356. var x=fa[n](a),
  357. m= x.match(/(.*)(\..*)$/);
  358. if(!m || !m[2]) m=['',x,''];
  359. x=pad9(m[2])+' '+m[1];
  360. sCells.push(x);
  361. }
  362. }else{
  363. for( a=0; a<tl; a++) sCells.push(fa[n](a));
  364. }
  365. }
  366.  
  367. function sort_fn(a,b){
  368. var x=sDir[a], y=sDir[b];
  369. if(x!=y) return ((x<y)? 1: -1);
  370. x= sCells[a], y= sCells[b];
  371. return x==y? 0: (((x>y)^ASC)<<1)-1;
  372. }
  373.  
  374. var CNn={content: 0, message: 1, age: 2}
  375.  
  376. function oClr(){
  377. var o= catcher.querySelectorAll('.fsort-butt,.fsort-time')
  378. for(var ol=o.length,i=0;i<ol;i++)
  379. o[i] && o[i].parentNode.removeChild(o[i]);
  380. }
  381. //
  382. function extclassName(){
  383. ext.className='fsort-butt'+ (prefs.ext? ' fsort-on': '' );
  384. }
  385. function clockclassName(){
  386. clock.className='fsort-butt'+ (prefs.dtStyle? '': ' fsort-on');
  387. }
  388. function upcclassName(){
  389. upc.className='fsort-butt'+ (prefs.upc? ' fsort-on': '' );
  390. }
  391. //
  392. function doSort(t){
  393. TB=outerNode(t,'TBODY');
  394. if(!TB){ _l( "*GHSFL* TBODY not found"); return; }
  395. var n = CNn[t.parentNode.className];
  396. if(typeof n=="undefined") n= CNn[t.parentNode.parentNode.className];
  397. if(typeof n=="undefined"){ _l( "*GHSFL* undefined col"); return; }
  398. if(t.id=='fsort-clock'){
  399. dtStyle.disabled = (prefs.dtStyle ^= 1);
  400. savePrefs();
  401. clockclassName();
  402. return;
  403. }
  404. if (t.id=='fsort-ext'){
  405. if(C[n].s) prefs.ext ^= 1;
  406. else prefs.ext= 1;
  407. savePrefs();
  408. extclassName();
  409. C[n].d^=C[n].s; // don't toggle dir on ext.click
  410. }else
  411. if (t.id=='fsort-upc'){
  412. if(C[n].s) prefs.upc ^= 1;
  413. else prefs.upc= 1;
  414. savePrefs();
  415. upcclassName();
  416. C[n].d^=C[n].s; // don't toggle case on upc.click
  417. }
  418. var tb=[],ix=[], i, tl,ti,tx;
  419. _l('n:'+n);
  420. tl=TB.rows.length;
  421. ASC=C[n].d^=C[n].s;
  422. for( i=0; i<tl; i++)
  423. ix.push(i);
  424. oClr();
  425. sort_p(n);
  426. ix.sort(sort_fn);
  427. for( i=0; i<tl; i++)
  428. tb.push(TB.rows[ix[i]]);
  429. for( i=tl-1; i>=0; i--)
  430. TB.removeChild(TB.rows[i]);
  431. for( i=0; i<tl; i++)
  432. TB.appendChild(tb[i]);
  433. setC(n);
  434. gitDir1(0);
  435. }
  436.  
  437. function onClik(e){doSort(e.target)}
  438.  
  439. function gitDir1(x){
  440. if(x && document.querySelector('.fsort-butt')) {
  441. _l('gitDir'+x+ '- already'); return;
  442. }
  443. _l('gitDir',x?'create':'refresh')
  444. var c,o;
  445. ca=[];
  446. c= D.querySelector('.file-wrap table.files td.content >span');
  447. if(!c){ _l( '*GHSFL* no content') ; return; }
  448. ca.push(c);
  449. c=D.querySelector('.file-wrap table.files td.message >span');
  450. if(!c){ _l( '*GHSFL* no messages'); return; }
  451. ca.push(c);
  452. c=D.querySelector('.file-wrap table.files td.age >span');
  453. if(!c){_l( '*GHSFL* no ages'); return; }
  454. ca.push(c);
  455. if(x){ oClr(); oa=[];
  456. o=D.createElement('span');
  457. o.textContent='';
  458. oa.push(o);
  459. o=o.cloneNode(true);
  460. oa.push(o);
  461. o=o.cloneNode(true);
  462. oa.push(o);
  463. clock=D.createElement('span');
  464. clock.id='fsort-clock'; clockclassName();
  465. ext=D.createElement('span');
  466. ext.id='fsort-ext'; extclassName();
  467. upc=D.createElement('span');
  468. upc.id='fsort-upc'; upcclassName();
  469. setDateTime();
  470. setC(-1);
  471. }
  472. o=insBefore(oa[0],ca[0]);
  473. o.appendChild(upc);
  474. o.appendChild(ext);
  475. insBefore(oa[1],ca[1]);
  476. o=insBefore(oa[2],ca[2]);
  477. o.appendChild(clock);
  478. }
  479.  
  480. function gitDir(){
  481. gitDir1(1);
  482. }
  483.  
  484. catcher= D.querySelector('#js-repo-pjax-container');
  485. if(!catcher){ _l( "*GHSFL* err0r"); return; }
  486.  
  487. catcher.addEventListener('mousedown',function(e){
  488. if(e.target.nodeName && e.target.nodeName=='SPAN' &&
  489. e.target.className.indexOf('fsort-butt')>-1)
  490. { onClik(e); }
  491. }
  492. ,false);
  493.  
  494. _l('startup()');
  495.  
  496. try {
  497. locStor = W.localStorage;
  498. tt=locStor.getItem("GHSFL");
  499. } catch(e){ locStor =null}
  500.  
  501. if(locStor && tt) try{
  502. var pa =JSON.parse(tt);
  503. for (var a in pa) prefs[a]=pa[a];
  504. _l('prefs:'+JSON.stringify(prefs));
  505. }catch(e){ console.log(e+"\n*GHSFL* bad prefs") }
  506.  
  507. css();
  508. dtStyle.disabled=(prefs.dtStyle===1);
  509.  
  510. gitDir();
  511. var target = catcher; //document.body; //D.querSelector('.file-wrap');
  512. var MO = window.MutationObserver;
  513. if(!MO) MO= window.WebKitMutationObserver;
  514. if(!MO) return;
  515. var __started=0;
  516. var mutI=0;
  517. var observer = new MO(function(mutations) {
  518.  
  519. for(var m,t, ml=mutations.length, i=0; i<ml; i++)
  520. {
  521. m=mutations[i],t = m.target;
  522. if( m.type=="attributes")
  523. {
  524. if( t.nodeName == 'DIV' &&
  525. t.className == "file-wrap"
  526. ){
  527. gitDir();
  528. return;
  529. }
  530. // patch for the very first page
  531. if( t.nodeName=='TIME' )
  532. {
  533. //_l('T'+mutI++,ml,' T:' +m.type,'N:'+t.nodeName ) ;
  534. if( t.parentNode.parentNode.className=="age" )
  535. {
  536. if(!catcher.querySelector('.fsort-butt'))
  537. gitDir(1); //chrome ?!11
  538. setDateTime(1);
  539. __started=1;
  540. return;
  541. }
  542. else continue;
  543. }
  544. }
  545. if( m.type=="childList" )
  546. {
  547. if( t.className=='age' )
  548. {
  549. if(!catcher.querySelector('.fsort-butt'))
  550. gitDir(1); //chrome ?!11
  551. _l('C'+mutI++,ml,' T:' +m.type,'N:'+t.nodeName,'C:'+ t.className,t.querySelector('TIME').textContent) ;
  552. setDateTime(1);
  553. return;
  554. }
  555. else continue;
  556. }
  557. }
  558. });
  559.  
  560. observer.observe(D.body, { attributes: true, childList: true, subtree: true } );
  561. /* attributes: true , childList: true, subtree: true,
  562. characterData: true, attributeOldValue:true, characterDataOldValue:true
  563. */
  564.  
  565. })()};