CF-rating-chart-patch

Some modification to make Codeforces rating chart better

当前为 2019-12-01 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name CF-rating-chart-patch
  3. // @version 0.0
  4. // @description Some modification to make Codeforces rating chart better
  5. // @match *://codeforces.com/profile/*
  6. // @grant none
  7. // @run-at document-start
  8. // @namespace https://gf.qytechs.cn/users/410786
  9. // ==/UserScript==
  10. const oldCode = String.raw`
  11. grid: { hoverable: true, markings: markings }
  12. };
  13.  
  14. var plot = $.plot($("#placeholder"), datas, options);
  15.  
  16. function showTooltip(x, y, contents) {
  17. $('<div id="tooltip">' + contents + '</div>').css( {
  18. position: 'absolute',
  19. display: 'none',
  20. top: y - 20,
  21. left: x + 10,
  22. border: '1px solid #fdd',
  23. padding: '2px',
  24. 'font-size' : '11px',
  25. 'background-color': '#fee',
  26. opacity: 0.80
  27. }).appendTo("body").fadeIn(200);
  28. }
  29.  
  30. var ctx = plot.getCanvas().getContext("2d");
  31.  
  32. var prev = -1;
  33. $("#placeholder").bind("plothover", function (event, pos, item) {
  34. if (item) {
  35. if (prev != item.dataIndex) {
  36. $("#tooltip").remove();
  37. var params = data[item.seriesIndex][item.dataIndex];
  38.  
  39. var total = params[1];
  40. var change = params[5] > 0 ? "+" + params[5] : params[5];
  41. var contestName = params[11];
  42. var contestId = params[2];
  43. var contestUrl = params[7];
  44. var rank = params[6];
  45. var title = params[8];
  46. var html = "= " + total + " (" + change + "), " + title + "<br/>"
  47. + "Rank: " + rank + "<br/>"
  48. + "<a href='" + contestUrl + "'>" + contestName + "</a>";
  49. if (change > 0)
  50. html += "<br/><a style='font-weight: bold;' href=\"/bestRatingChanges/" + params[10] + "\">Share it!</a>";
  51. showTooltip(item.pageX, item.pageY, html);
  52. setTimeout(function () {
  53. $("#tooltip").fadeOut(200);
  54. prev = -1;
  55. }, 4000);
  56. prev = item.dataIndex;
  57. }
  58. }
  59. });`;
  60.  
  61. const newCode = '\ngrid: { hoverable: true, clickable: true, markings: markings } };' + (function(){
  62. // NOTE: toString does not work 100% of the time. Use String.raw instead if it doesn't work.
  63. var plot = $.plot($("#placeholder"), datas, options);
  64.  
  65. function showTooltip(x, y, contents) {
  66. $('<div id="tooltip">' + contents + '</div>').css( {
  67. position: 'absolute',
  68. display: 'none',
  69. top: y - 20,
  70. left: x,
  71. border: '1px solid #fdd',
  72. padding: '2px',
  73. 'font-size' : '11px',
  74. 'background-color': '#fee',
  75. opacity: 0.80
  76. }).appendTo("body").fadeIn(200);
  77. }
  78.  
  79. var ctx = plot.getCanvas().getContext("2d");
  80.  
  81. $("#placeholder").bind("plotclick", function (event, pos, item) {
  82. if (item) {
  83. var params = data[item.seriesIndex][item.dataIndex];
  84.  
  85. var total = params[1];
  86. var change = params[5] > 0 ? "+" + params[5] : params[5];
  87. var contestName = params[11];
  88. var contestId = params[2];
  89. var contestUrl = params[7];
  90. var rank = params[6];
  91. var title = params[8];
  92.  
  93. window.open(contestUrl)
  94. }
  95. });
  96.  
  97. var prev = -1;
  98. var tooltipFadeoutTimeoutId = null;
  99.  
  100. function clearTooltipFadeout () {
  101. if (tooltipFadeoutTimeoutId !== null)
  102. clearTimeout(tooltipFadeoutTimeoutId);
  103. }
  104.  
  105. function setTooltipFadeout () {
  106. clearTooltipFadeout();
  107. tooltipFadeoutTimeoutId = setTimeout(function () {
  108. $("#tooltip").fadeOut(200);
  109. prev = -1;
  110. tooltipFadeoutTimeoutId = null;
  111. }, 4000);
  112. }
  113.  
  114. $("#placeholder").bind("plothover", function (event, pos, item) {
  115. if (item) {
  116. if (prev != item.dataIndex) {
  117. $("#tooltip").remove();
  118. var params = data[item.seriesIndex][item.dataIndex];
  119.  
  120. var total = params[1];
  121. var change = params[5] > 0 ? "+" + params[5] : params[5];
  122. var contestName = params[11];
  123. var contestId = params[2];
  124. var contestUrl = params[7];
  125. var rank = params[6];
  126. var title = params[8];
  127. var html = "= " + total + " (" + change + "), " + title + "<br/>"
  128. + "Rank: " + rank + "<br/>"
  129. + "<a href='" + contestUrl + "'>" + contestName + "</a>";
  130. if (change > 0)
  131. html += "<br/><a style='font-weight: bold;' href=\"/bestRatingChanges/" + params[10] + "\">Share it!</a>";
  132. showTooltip(item.pageX, item.pageY, html);
  133. prev = item.dataIndex;
  134.  
  135. $("#tooltip").bind("mouseenter", clearTooltipFadeout).bind("mouseleave", setTooltipFadeout);
  136. }
  137. } else {
  138. setTooltipFadeout();
  139. }
  140. }).bind("mouseleave", setTooltipFadeout);
  141. // this will always work because mouseleave of placeholder is fired before
  142. // mouseenter of tooltip (stackoverflow.com/q/10011493)
  143.  
  144. }).toString().replace(/}$/,'').replace(/^function.*?(\s*)\s*{/,'')
  145.  
  146.  
  147. var script_modified = false;
  148. new MutationObserver(function(mutations, observer){
  149. for (let r of mutations){
  150. let t=r.target
  151. if(t.tagName==='SCRIPT'){
  152. var ind = t.innerHTML.indexOf(oldCode);
  153. if (ind >= 0) {
  154. t.innerHTML = t.innerHTML.substr(0, ind) + newCode + t.innerHTML.substr(ind+oldCode.length)
  155. observer.disconnect();
  156. script_modified = true;
  157. console.log('CF script modified')
  158. return;
  159. }
  160. }
  161. }
  162. }).observe(document,{
  163. childList:true,
  164. subtree:true,
  165. });
  166.  
  167. window.addEventListener('load', function(){
  168. if (!script_modified)
  169. console.log('NOTE: script is not working')
  170. })

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址