atcoder-problem-navigator

Shows a navigation bar on AtCoder and Codeforces contest pages for jumping to problems.

Från och med 2019-12-07. Se den senaste versionen.

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 atcoder-problem-navigator
  3. // @namespace https://github.com/yoshrc
  4. // @version 1.3
  5. // @description Shows a navigation bar on AtCoder and Codeforces contest pages for jumping to problems.
  6. // @author yoshrc
  7. // @include https://atcoder.jp/contests/*
  8. // @include https://codeforces.com/contest/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. const KEY_PREFIX = 'atcoder-problem-navigator-';
  16.  
  17. const do_atcoder = () => {
  18. const contest = location.href.match(/^https:\/\/atcoder\.jp\/contests\/([^\/]+)/)[1];
  19. const key = KEY_PREFIX + contest;
  20.  
  21. if (location.href.match(/^https:\/\/atcoder\.jp\/contests\/([^\/]+)\/tasks\/?$/)) {
  22. const problems = [];
  23. const rows = document.querySelectorAll('tbody>tr');
  24. for (let i = 0; i < rows.length; i++) {
  25. const links = rows[i].querySelectorAll('a');
  26. const href = links[0].getAttribute('href');
  27. const text = links[0].textContent + ' - ' + links[1].textContent;
  28. problems.push({
  29. href: href,
  30. text: text
  31. });
  32. }
  33. localStorage[key] = JSON.stringify(problems);
  34. }
  35.  
  36. if (key in localStorage) {
  37. let problems = JSON.parse(localStorage[key]);
  38. const problemsBar = document.createElement('ul');
  39. problemsBar.className = 'nav nav-tabs';
  40. for (let i = 0; i < problems.length; i++) {
  41. const link = document.createElement('a');
  42. link.setAttribute('style', 'margin-left: 10px; margin-right: 10px; white-space: nowrap');
  43. link.setAttribute('href', problems[i].href);
  44. link.textContent = problems[i].text;
  45. const span = document.createElement('span');
  46. span.textContent = ' ';
  47. span.appendChild(link);
  48. problemsBar.appendChild(span);
  49. }
  50. document.getElementById('contest-nav-tabs').appendChild(problemsBar);
  51. }
  52. };
  53.  
  54. const do_codeforces = () => {
  55. const contest = location.href.match(/^https:\/\/codeforces\.com\/contest\/([^\/]+)/)[1];
  56. const key = KEY_PREFIX + contest;
  57.  
  58. if (location.href.match(/^https:\/\/codeforces\.com\/contest\/([^\/]+)\/?$/)) {
  59. const problems = [];
  60. const rows = document.querySelectorAll('.problems>tbody>tr');
  61. // Starts from 1 to skip the header
  62. for (let i = 1; i < rows.length; i++) {
  63. const links = rows[i].querySelectorAll('a');
  64. const href = links[0].getAttribute('href');
  65. const text = links[0].textContent + '. ' + links[1].textContent;
  66. problems.push({
  67. href: href,
  68. text: text
  69. });
  70. }
  71. localStorage[key] = JSON.stringify(problems);
  72. }
  73.  
  74. if (key in localStorage) {
  75. let problems = JSON.parse(localStorage[key]);
  76. const problemsBar = document.createElement('ul');
  77. problemsBar.setAttribute('style', 'margin-left: 15px; margin-right: 280px; padding-top: 30px');
  78. for (let i = 0; i < problems.length; i++) {
  79. const link = document.createElement('a');
  80. link.setAttribute('style', 'margin-right: 20px; white-space: nowrap');
  81. link.setAttribute('href', problems[i].href);
  82. link.textContent = problems[i].text;
  83. const span = document.createElement('span');
  84. span.textContent = ' ';
  85. span.appendChild(link);
  86. problemsBar.appendChild(span);
  87. }
  88.  
  89. const content = document.getElementById('pageContent');
  90. content.parentNode.insertBefore(problemsBar, content);
  91. }
  92. };
  93.  
  94. if (location.href.match(/^https:\/\/atcoder\.jp\/contests\//)) {
  95. do_atcoder();
  96. } else if (location.href.match(/^https:\/\/codeforces\.com\/contest\//)) {
  97. do_codeforces();
  98. }
  99. })();