Habr Percentage Ring

Percentage Rings around numbers which show grades (for with userstyles)

  1. // ==UserScript==
  2. // @id HabrPercentageRing
  3. // @name Habr Percentage Ring
  4. // @version 15.2016.3.7
  5. // @namespace github.com/spmbt
  6. // @author spmbt0
  7. // @description Percentage Rings around numbers which show grades (for with userstyles)
  8. // @icon https://habrahabr.ru/favicon.ico
  9. // @include https://habrahabr.ru*
  10. // @include https://geektimes.ru*
  11. // @include /^https?://(m\.|webcache\.googleusercontent\.com\/search\?q=cache(:|%3A|%3a)(https?(:|%3A|%3a)(\/|%2F|%2f)(\/|%2F|%2f))?)?(habrahabr|geektimes|megamozg|h).ru(?!\/special|\/api)/
  12. // @exclude https://habrahabr.ru/api/*
  13. // @update 14 https
  14. // ==/UserScript==
  15. // работает автономно или как модуль для HabrAjax: https://greasyfork.org/en/scripts/1970-habrajax
  16. var w1n = typeof unsafeWindow !='undefined'? unsafeWindow: (function(){return this})();
  17. (w1n.habrPercentageRing = function(blck){
  18. var marks = blck && blck.childNodes && blck.querySelectorAll('.voting-wjt__counter')
  19. ,r2 = 14
  20. ,isC2 = blck && / c2/.test(blck.className)
  21. ,$q = function(q, f){return (f||document).querySelector(q)}
  22. ,zen = (function(a, b){ //индикатор подключения юзерстилей ZenComment
  23. a = $q(b) || $q(a); //b - устаревший переходной индикатор, a - входящий в действие
  24. b = a && w1n.getComputedStyle(a, null);
  25. return !!(b && (b.getPropertyValue('z-index')=='10026' || b.getPropertyValue('max-width')=='1420px'));})('.nav_panel .tab_user','#navbar')
  26. ,isHajax = function(){return !!$q('.hAjaxLogo');};
  27. if(!marks) return;
  28. for(var i in marks){
  29. var o = marks[i]
  30. ,oP = o.parentNode;
  31. if(!o || !o.attributes) continue;
  32. o.style.position ='relative';
  33. if(/\/users\//.test(location.href) ){
  34. oP.style.marginRight ='14px';
  35. oP.style.marginTop ='2px';}
  36. var oXS = $q('span', o);
  37. if(oXS && oXS.getAttribute('title')){
  38. var oXSt = oXS.getAttribute('title').match(/[\d\.]+/g)
  39. ,oC = $q('canvas', o)
  40. ,hajax = isHajax();
  41. if(oC) oC.parentNode.removeChild(oC);
  42. if(oXSt && oXSt.length && !$q('canvas', o)){
  43. var aP = oXSt[1], aM = oXSt[2]
  44. ,abs = Math.abs(aP - aM)
  45. ,c = (function(aP, aM){ //writePercRound
  46. var aPM = Number(aP) + Number(aM);
  47. if(aPM ==0) return document.createElement('div');
  48. var c = document.createElement('canvas')
  49. , pi = Math.PI, r2 = 14, ell = 1-1/3.6;
  50. c.width = c.height = r2 *2;
  51. c.style.backgroundColor ='transparent';
  52. c.style.position ='absolute';
  53. c.style.left = (-r2 +12) +'px';
  54. c.style.top = (-r2 +1 +8) +'px';
  55. var q = c.getContext("2d")
  56. , log = Math.log(aPM)/1.6 +1;
  57. c.style.opacity = 0.25 + log *0.1;
  58. c.style.zIndex = 1;
  59. q.beginPath();
  60. q.lineWidth = log;
  61. q.strokeStyle ='#1b1';
  62. var perc = (0.5- aM/aPM)* pi
  63. , perc2 = (0.5+ aM/aPM)* pi;
  64. q.scale(1, ell);
  65. q.arc(r2, r2 /ell, r2 -1, perc, perc2 +2*(perc == perc2 && aP !=0)*pi, aP ==0 || aM !=0);
  66. q.stroke();
  67. q.beginPath();
  68. q.strokeStyle ='#a24';
  69. q.arc(r2, r2/ell, r2 -1, perc, perc2 +2*(perc == perc2 && aM !=0)*pi, !1);
  70. q.stroke();
  71. return c;
  72. })(aP, aM, (function(obj){ //getPositionCenter
  73. var x =0, y =0
  74. ,w2 = Math.floor(obj.offsetWidth /2)
  75. ,h2 = Math.floor(obj.offsetHeight /2);
  76. while(obj){ x += obj.offsetLeft; y += obj.offsetTop; obj = obj.offsetParent;}
  77. return {x: x, y: y, w2: w2, h2: h2};
  78. })(o))
  79. ,oPM = $q('.minus', oP)
  80. ,oPP = $q('.plus', oP)
  81. ,oPPI = /postinfo-panel__item/.test(oP.parentNode.className);
  82. //console.log('oPM', oPM)
  83. if(oPM && (-aP - aM))
  84. oPM.style.left =(oPPI ? 46 : (abs >9 ? 32 : 26))+'px';
  85. if(oPPI){ //article
  86. oXS.style.left ='-1px';
  87. c.style.left = -r2 + (abs >99 ? 17 : (abs >9 ? 11 : (abs ? 7 : 3))) +'px';
  88. c.style.top = 5 - (hajax && 0) +'px';
  89. }else{ //comments
  90. oXS.style.left = (abs ? -1 : 7)+'px';
  91. oXS.style.top =0;
  92. c.style.left = -1 -r2 + (abs >99 ? 18 : (abs >9 ? 11 : (abs ? 7 : 8))) -(isC2 && 1) +(zen && 0) +'px';
  93. c.style.top = 1+ (isC2 ? -5 + zen : -3) +(zen && 0) +'px';
  94. }
  95. oXS.style.position ='relative';
  96. o.insertBefore(c, oXS);
  97. if(oPPI && abs >99)
  98. o.style.left ='-9px';
  99. oXS.style.zIndex =2;
  100. (function(oP){
  101. var ff = function(){setTimeout(function(){
  102. w1n.habrPercentageRing(oP)},2999)};
  103. oPM && oPM.addEventListener('click',ff,!1);
  104. oPP && oPP.addEventListener('click',ff,!1);
  105. })(oP)
  106. }}}
  107. })(document);
  108.  
  109. w1n.addEventListener('chgDom', function(ev){ //проверить блок по событию от модулей (Fx6+, Chrome,Safari)
  110. w1n.habrPercentageRing(ev.detail);
  111. },!1);