Codeforces charged

(Codeforces) Wide problems UI. Keyboard shortcuts. Quick navigation to submission and solutions pages on Codeforces.

  1. // ==UserScript==
  2. // @name Codeforces charged
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @author Dev vikram Singh
  6. // @match https://codeforces.com/contest/*
  7. // @grant none
  8. // @license MIT
  9. // @description (Codeforces) Wide problems UI. Keyboard shortcuts. Quick navigation to submission and solutions pages on Codeforces.
  10. // @noframes
  11. // ==/UserScript==
  12. // jshint esversion: 11
  13.  
  14. ( function () {
  15. 'use strict';
  16.  
  17. // Function to apply styles to the body and footer logo
  18. function applyStyles ( bodyElem ) {
  19. const footerLogoDiv = document.querySelector( ".footer-logo-div" );
  20.  
  21. if ( bodyElem )
  22. {
  23. bodyElem.style.cssText = "margin: 0; max-width: 100%;"; // Batch style updates
  24. }
  25. if ( footerLogoDiv )
  26. {
  27. footerLogoDiv.style.position = "inherit"; // Apply footer style
  28. }
  29. }
  30.  
  31. // Create a MutationObserver to apply styles when the body is available
  32. const observer = new MutationObserver( ( mutations ) => {
  33. for ( const mutation of mutations )
  34. {
  35. const bodyElem = document.getElementById( "body" );
  36. if ( mutation.type === "childList" && bodyElem )
  37. {
  38. applyStyles( bodyElem );
  39. observer.disconnect();
  40. break;
  41. }
  42. }
  43. } );
  44.  
  45. // Start observing the document body for child additions
  46. observer.observe( document.body, { childList: true, subtree: true } );
  47.  
  48. const currentURL = window.location.href;
  49. const contestRegex = /\/contest\/(\d+)/;
  50. const match = currentURL.match( contestRegex );
  51. const check = currentURL.includes( "/problem/", 30 );
  52.  
  53. // Function to handle keydown event
  54. function handleKeyDown ( event ) {
  55. if ( event.altKey && event.key === 's' && check )
  56. {
  57. let newURL = currentURL.replace( "/problem/", "/submit/" );
  58. window.location.href = newURL;
  59. }
  60. if ( event.altKey && event.key === 'a' && check )
  61. {
  62. let newURL = currentURL.replace( "/problem/", "/status/" ) + "?order=BY_CONSUMED_TIME_ASC";
  63. window.location.href = newURL;
  64. }
  65. }
  66.  
  67. // Fetch and store problem names and IDs
  68. async function fetchProblemData () {
  69. if ( !match ) return;
  70.  
  71. const contestId = match[ 1 ];
  72. const storedContestId = localStorage.getItem( 'contestId' );
  73.  
  74. // Clear stored data if the contest ID has changed
  75. if ( storedContestId !== contestId )
  76. {
  77. localStorage.removeItem( 'problemData' );
  78. localStorage.removeItem( 'contestId' );
  79. }
  80.  
  81. let problemData = []; // Initialize an empty array to store problem data
  82.  
  83. // Check if problemData is already stored
  84. if ( !localStorage.getItem( 'problemData' ) )
  85. {
  86. try
  87. {
  88. const response = await fetch( `https://codeforces.com/contest/${ contestId }` );
  89. const data = await response.text();
  90. const tempDiv = document.createElement( 'div' );
  91. tempDiv.innerHTML = data;
  92. const problemRows = tempDiv.querySelectorAll( 'table.problems tbody tr' );
  93.  
  94. // Populate problemData array
  95. problemRows.forEach( ( row, index ) => {
  96. if ( index > 0 )
  97. { // Skip header row
  98. const cells = row.querySelectorAll( 'td' );
  99. const problemId = cells[ 0 ]?.querySelector( 'a' )?.textContent.trim();
  100. const problemName = cells[ 1 ]?.querySelector( 'a' )?.textContent.trim();
  101.  
  102. if ( problemId && problemName )
  103. {
  104. problemData.push( { id: problemId, name: problemName } );
  105. }
  106. }
  107. } );
  108.  
  109. // Store fetched problem data in localStorage
  110. localStorage.setItem( 'problemData', JSON.stringify( problemData ) );
  111. localStorage.setItem( 'contestId', contestId );
  112. } catch ( error )
  113. {
  114. console.error( 'Error fetching contest problems:', error );
  115. return; // Exit if there was an error fetching the data
  116. }
  117. } else
  118. {
  119. // Retrieve existing problem data from localStorage
  120. problemData = JSON.parse( localStorage.getItem( 'problemData' ) );
  121. }
  122.  
  123. // Generate the problem data regardless of where it came from
  124. if ( check && problemData.length > 0 )
  125. {
  126. generateProblemData( problemData );
  127. }
  128. }
  129.  
  130. // Function to generate and insert problem data links
  131. async function generateProblemData ( problemData ) {
  132. const list = document.createElement( 'ul' );
  133. list.style.margin = '10px 0 20px'; // Add some space below
  134.  
  135. problemData.forEach( problem => {
  136. const listItem = document.createElement( 'li' );
  137. const link = document.createElement( 'a' );
  138. link.href = `https://codeforces.com/contest/${ match[ 1 ] }/problem/${ problem.id }`;
  139. link.textContent = `${ problem.id }: ${ problem.name }`;
  140. link.target = '_blank'; // Open in a new tab
  141. link.setAttribute( "style", "display: block; color: orange;width : 100%; text-decoration : none" );
  142.  
  143. listItem.style.margin = '5px';
  144. listItem.appendChild( link );
  145. list.appendChild( listItem );
  146. } );
  147.  
  148. const sidebar = document.getElementById( 'sidebar' );
  149. if ( sidebar )
  150. {
  151. sidebar.insertBefore( list, sidebar.children[ 1 ] );
  152. }
  153. }
  154.  
  155. // Call fetchProblemData on page load to handle storing/loading problems
  156. fetchProblemData();
  157.  
  158. // Add event listener for keydown event
  159. document.addEventListener( 'keydown', handleKeyDown );
  160. } )();

QingJ © 2025

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