Greasy Fork is available in English.

codeforces-problem-queue

You can queue the problems you want to revenge!

  1. // ==UserScript==
  2. // @name codeforces-problem-queue
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description You can queue the problems you want to revenge!
  6. // @author itohdak
  7. // @license MIT
  8. // @match https://codeforces.com/contest/*/problem/*
  9. // @match https://codeforces.com/profile/*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. var max_problem_count = 50;
  14. function getProblemQueue () {
  15. return JSON.parse(localStorage.getItem('problemQueue') || '{}');
  16. }
  17. function setProblemQueue (problemQueue) {
  18. localStorage.setItem('problemQueue', JSON.stringify(problemQueue));
  19. }
  20. function addProblem (problemTitle, problemContent) {
  21. var problemQueue = getProblemQueue();
  22. if(problemTitle in problemQueue) {
  23. return "Already in queue.";
  24. } else if(Object.keys(problemQueue).length >= max_problem_count) {
  25. return "Reached the maximum number of problems you can queue.</br>Let\'s solve the problems!:)";
  26. } else {
  27. problemQueue[problemTitle] = problemContent;
  28. setProblemQueue(problemQueue);
  29. return "Added successfully.";
  30. }
  31. }
  32. function deleteProblem (problemTitle) {
  33. var problemQueue = getProblemQueue();
  34. delete problemQueue[problemTitle];
  35. setProblemQueue(problemQueue);
  36. }
  37.  
  38. function setAddProblemButton () {
  39. // Create a button in a container div.
  40. var div = document.createElement('div');
  41. div.setAttribute('style', 'margin:1em;font-size:0.8em;');
  42. div.setAttribute('id', 'addProblemContainer');
  43. var btn = document.createElement('input');
  44. btn.setAttribute('type', 'submit');
  45. btn.setAttribute('value', 'Add this problem to my problem queue');
  46. btn.setAttribute('style', 'padding:0 0.5em;');
  47. btn.setAttribute('id', 'addProblemButton');
  48. div.appendChild(btn);
  49. document.getElementsByClassName('header')[0].appendChild(div);
  50.  
  51. // Activate the newly added button.
  52. document.getElementById('addProblemButton').addEventListener(
  53. 'click', buttonClickAction, false
  54. );
  55. }
  56.  
  57. function buttonClickAction (event) {
  58. var problemTitle = document.getElementsByClassName('title')[0].innerHTML
  59. var contestName = document.getElementsByClassName('left')[0].querySelectorAll('a')[0].text
  60. var msg = addProblem(problemTitle, {'contestName': contestName, 'problemLink': location.href});
  61.  
  62. var p = document.createElement('p');
  63. p.innerHTML = '<font color="red">' + msg + '</font>';
  64. var cntr = document.getElementById('addProblemContainer');
  65. if(cntr.children.length > 1) cntr.removeChild(cntr.childNodes[1]);
  66. cntr.appendChild(p);
  67. }
  68.  
  69. function createCodeforcesLikeRoundBox () {
  70. var roundBox = document.createElement('div');
  71. roundBox.setAttribute('class', 'roundbox sidebox top-contributed');
  72. roundBox.setAttribute('style', 'margin-top:1em;');
  73. var roundBoxLT = document.createElement('div');
  74. roundBoxLT.setAttribute('class', 'roundbox-lt');
  75. roundBoxLT.innerHTML = '&nbsp;';
  76. var roundBoxRT = document.createElement('div');
  77. roundBoxRT.setAttribute('class', 'roundbox-rt');
  78. roundBoxRT.innerHTML = '&nbsp;';
  79. var roundBoxLB = document.createElement('div');
  80. roundBoxLB.setAttribute('class', 'roundbox-lb');
  81. roundBoxLB.innerHTML = '&nbsp;';
  82. var roundBoxRB = document.createElement('div');
  83. roundBoxRB.setAttribute('class', 'roundbox-rb');
  84. roundBoxRB.innerHTML = '&nbsp;';
  85. roundBox.appendChild(roundBoxLT);
  86. roundBox.appendChild(roundBoxRT);
  87. // roundBox.appendChild(roundBoxLB);
  88. // roundBox.appendChild(roundBoxRB);
  89. return roundBox;
  90. }
  91.  
  92. function createCodeforcesLikeDeleteButton (problemTitle) {
  93. var deleteBtn = document.createElement('a');
  94. deleteBtn.setAttribute('class', 'delete-virtual-contest');
  95. deleteBtn.setAttribute('title', 'delete [' + problemTitle + ']');
  96. deleteBtn.setAttribute('href', '#');
  97. var img = document.createElement('img');
  98. img.setAttribute('width', '12px;');
  99. img.setAttribute('src', '//sta.codeforces.com/s/!/images/delete.png');
  100. deleteBtn.appendChild(img);
  101. return deleteBtn;
  102. }
  103.  
  104. function setProblemList () {
  105. var userPage = document.getElementsByClassName('avatar')[0].querySelectorAll('a')[1];
  106. if(userPage == null || (userPage != location.href && userPage + "#" != location.href)) return;
  107.  
  108. var roundBox = createCodeforcesLikeRoundBox();
  109.  
  110. var title = document.createElement('div');
  111. title.setAttribute('class', 'caption titled');
  112. title.innerHTML = '→ Problem queue';
  113. roundBox.appendChild(title);
  114.  
  115. var table = document.createElement('table');
  116. table.setAttribute('class', 'rtable ');
  117. table.setAttribute('id', 'problemQueue');
  118. roundBox.appendChild(table);
  119. var tbody = document.createElement('tbody');
  120. table.appendChild(tbody);
  121.  
  122. var header = document.createElement('tr');
  123. var thIdx = document.createElement('th');
  124. thIdx.textContent = '#';
  125. var thPblm = document.createElement('th');
  126. thPblm.textContent = 'Problem';
  127. header.appendChild(thIdx);
  128. header.appendChild(thPblm);
  129. header.appendChild(document.createElement('th'));
  130. tbody.appendChild(header);
  131.  
  132. var num = 1;
  133. var problemQueue = getProblemQueue();
  134. for (let key in problemQueue) {
  135. var tr = document.createElement('tr');
  136. // add index
  137. var tdIdx = document.createElement('td');
  138. tdIdx.innerText = num;
  139. if(num%2) tdIdx.setAttribute('class', 'dark');
  140. // add problem link
  141. var tdLink = document.createElement('td');
  142. if(num%2) tdLink.setAttribute('class', 'dark');
  143. tdLink.innerHTML = '<a href="' + problemQueue[key].problemLink + '" title="' + problemQueue[key].contestName + '" target="_blank" rel="noopener noreferrer">' + key + '</a>';
  144. // add delete button
  145. var tdBtn = document.createElement('td');
  146. if(num%2) tdBtn.setAttribute('class', 'dark');
  147. tdBtn.appendChild(createCodeforcesLikeDeleteButton(key));
  148. tr.appendChild(tdIdx);
  149. tr.appendChild(tdLink);
  150. tr.appendChild(tdBtn);
  151. tbody.appendChild(tr);
  152. num++;
  153. }
  154. document.getElementById('pageContent').appendChild(roundBox);
  155.  
  156. document.querySelectorAll('.delete-virtual-contest').forEach ( (btn) => btn.addEventListener (
  157. 'click', {obj: btn, handleEvent: deleteAction}, false
  158. ));
  159. }
  160.  
  161. function deleteAction (event) {
  162. var tr = this.obj.parentNode.parentNode;
  163. var problemTitle = tr.querySelectorAll('a')[0].text;
  164. deleteProblem(problemTitle);
  165. tr.parentNode.deleteRow(tr.sectionRowIndex);
  166. }
  167.  
  168. (function() {
  169. var url = window.location.href;
  170.  
  171. if( url.match(new RegExp('/codeforces.com\/contest\/(.*)\/problem\/(.*)')) != null ) {
  172. setAddProblemButton();
  173. } else if ( url.match(new RegExp('/codeforces.com\/profile\/(.*)')) != null) {
  174. setProblemList();
  175. }
  176. })();