change-Codeforces-UI

CHANGE CODEFORCES UGLY UI TO ANOTHER UGLY UI BY FUNCDFS

当前为 2024-05-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name change-Codeforces-UI
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description CHANGE CODEFORCES UGLY UI TO ANOTHER UGLY UI BY FUNCDFS
  6. // @author funcdfs
  7. // @match https://atcoder.jp/contests/*
  8. // @match https://codeforces.com/*/problem/*
  9. // @match https://codeforces.com/contest/*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=codeforces.com
  11. // @grant none
  12. // @license MIT
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. 'use strict';
  17. const codeforces_css = () => {
  18. const styleTag = document.createElement('style');
  19. const cssRules = `
  20. pre {
  21. font-family: source code pro;
  22. }
  23. div.ttypography tbody td {
  24. text-align: left;
  25. border-top: 0px solid #ccc;
  26. }
  27. body {
  28. background-color: #e7e9ed0f;
  29. }
  30. .roundbox-lt,
  31. .roundbox-rt,
  32. .roundbox-lb,
  33. .roundbox-rb {
  34. display: none;
  35. }
  36. .roundbox {
  37. padding-bottom: 10px;
  38. border-radius: 10px;
  39. }
  40. .sidebox.roundbox {
  41. margin-top: 10px;
  42. }
  43. .menu-box {
  44. margin-top: 0px !important;
  45. -webkit-transition: none !important;
  46. -moz-transition: none !important;
  47. -ms-transition: none !important;
  48. -o-transition: none !important;
  49. transition: none !important;
  50. }
  51. .menu-box:hover {
  52. -webkit-box-shadow: none !important;
  53. -moz-box-shadow: none !important;
  54. box-shadow: none !important;
  55. }
  56. /** Custom sidebar */
  57. .roundbox {
  58. margin-top: 10px;
  59. border: none;
  60. -webkit-transition: all 0.3s linear 0s;
  61. -moz-transition: all 0.3s linear 0s;
  62. -ms-transition: all 0.3s linear 0s;
  63. -o-transition: all 0.3s linear 0s;
  64. transition: all 0.3s linear 0s;
  65. }
  66. .roundbox:hover {
  67. -webkit-box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.1);
  68. -moz-box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.1);
  69. box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.1);
  70. }
  71. .roundbox .titled {
  72. padding: 10px;
  73. border-bottom-color: #e4e6eb;
  74. }
  75. .sidebox div {
  76. border-bottom-color: #e4e6eb !important;
  77. }
  78.  
  79. /** Sidebar avatar custom */
  80. .personal-sidebar .for-avatar {
  81. float: none !important;
  82. display: block;
  83. font-size: 18px;
  84. padding: 10px;
  85. }
  86.  
  87. .personal-sidebar .for-avatar .avatar img {
  88. border-radius: 50px;
  89. width: 90px;
  90. height: 90px;
  91. object-fit: cover;
  92. }
  93.  
  94. /** Sidebar remove property links*/
  95. .personal-sidebar .propertyLinks {
  96. display: none;
  97. }
  98.  
  99. .personal-sidebar .nav-links {
  100. border-top-style: solid;
  101. border-top-width: 1px;
  102. border-top-color: #e4e6eb;
  103. padding-top: 10px;
  104. }
  105.  
  106. .personal-sidebar .nav-links li {
  107. list-style-type: none !important;
  108. padding: 10px;
  109. font-size: 13px;
  110. border-radius: 5px;
  111. -webkit-transition: all 0.2s linear 0s;
  112. -moz-transition: all 0.2s linear 0s;
  113. -ms-transition: all 0.2s linear 0s;
  114. -o-transition: all 0.2s linear 0s;
  115. transition: all 0.2s linear 0s;
  116. }
  117.  
  118. .personal-sidebar .nav-links li a,
  119. .personal-sidebar .nav-links li a:visited {
  120. color: #050505;
  121. }
  122.  
  123. .personal-sidebar .nav-links li:after {
  124. content: '→';
  125. float: right;
  126. color: #050505;
  127. }
  128.  
  129. .personal-sidebar .nav-links li:hover {
  130. background-color: rgba(0, 0, 0, 0.05);
  131. }
  132.  
  133. .personal-sidebar .nav-links li a {
  134. text-decoration: none !important;
  135. }
  136.  
  137. .roundbox .bottom-links {
  138. padding: 10px;
  139. background-color: #fff;
  140. border-top-color: #e4e6eb !important;
  141. border-bottom-left-radius: 10px !important;
  142. border-bottom-right-radius: 10px !important;
  143. }
  144.  
  145. .roundbox .rtable .dark {
  146. background-color: #fff;
  147. }
  148. /** Topic custom */
  149. .topic {
  150. margin-top: 10px;
  151. padding: 20px;
  152. background-color: #fff;
  153. border-radius: 10px;
  154. -webkit-transition: all 0.3s linear 0s;
  155. -moz-transition: all 0.3s linear 0s;
  156. -ms-transition: all 0.3s linear 0s;
  157. -o-transition: all 0.3s linear 0s;
  158. transition: all 0.3s linear 0s;
  159. }
  160.  
  161. .topic:hover {
  162. -webkit-box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  163. -moz-box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  164. box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  165. }
  166.  
  167. .topic .roundbox {
  168. border-style: solid;
  169. border-color: #e4e6eb;
  170. }
  171.  
  172. .topic .meta a {
  173. text-decoration: none;
  174. }
  175.  
  176. .meta {
  177. padding-bottom: 0px !important;
  178. }
  179.  
  180. .topic .content {
  181. border-left-color: #e4e6eb;
  182. }
  183. .roundbox .rtable td,
  184. .roundbox .rtable th {
  185. border-bottom: 1px solid #e4e6eb;
  186. border-left: none;
  187. padding: 7px;
  188. }
  189.  
  190. /** Header custom */
  191. #header {
  192. padding: 20px;
  193. margin-top: -14px;
  194. background-color: #fff;
  195. }
  196.  
  197. .menu-box {
  198. padding: 10px;
  199. border-radius: 0;
  200. border-top: none;
  201. border-left: none;
  202. border-right: none;
  203. border-bottom-left-radius: 20px;
  204. border-bottom-right-radius: 20px;
  205. border-bottom-color: #e4e6eb;
  206. }
  207.  
  208. /** Footer custom */
  209. #footer {
  210. background-color: #fff;
  211. width: 100%;
  212. height: 100%;
  213. border-top-left-radius: 20px;
  214. border-top-right-radius: 20px;
  215. border-top-color: #e4e6eb;
  216. }
  217.  
  218. /** Contest data table */
  219. .datatable .lt,
  220. .datatable .rt,
  221. .datatable .lb,
  222. .datatable .rb,
  223. .datatable .ilt,
  224. .datatable .irt {
  225. display: none;
  226. }
  227.  
  228. .datatable table {
  229. margin-top: 10px;
  230. border-style: solid;
  231. border-color: #e4e6eb;
  232. border-width: 1px;
  233. }
  234.  
  235. .datatable table .dark {
  236. background-color: #fff;
  237. }
  238.  
  239. .datatable table td {
  240. padding-top: 5px;
  241. padding-bottom: 5px;
  242. padding-left: 10px;
  243. padding-right: 10px;
  244. }
  245.  
  246. .datatable {
  247. padding: 20px !important;
  248. width: inherit;
  249. padding-bottom: 40px !important;
  250. background-color: #fff !important;
  251. border-radius: 10px;
  252. -webkit-transition: all 0.3s linear 0s;
  253. -moz-transition: all 0.3s linear 0s;
  254. -ms-transition: all 0.3s linear 0s;
  255. -o-transition: all 0.3s linear 0s;
  256. transition: all 0.3s linear 0s;
  257. }
  258.  
  259. .datatable:hover {
  260. -webkit-box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  261. -moz-box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  262. box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  263. }
  264.  
  265. .contests-table::first-line {
  266. font-size: 20px;
  267. font-weight: bold !important;
  268. }
  269.  
  270.  
  271. .datatable {
  272. margin-top: 10px !important;
  273. }
  274.  
  275. /** Custom input */
  276. input[type="file"] {
  277. padding: 2px 2px!important;
  278. border: none !important;
  279. }
  280.  
  281. input,
  282. button {
  283. outline: none;
  284. height: auto !important;
  285. padding: 5px 30px 5px 30px !important;
  286. border-radius: 10px;
  287. border-width: 1.5px;
  288. border-color: #3b5998;
  289. font-weight: normal;
  290. -webkit-transition: all 0.3s linear 0s;
  291. -moz-transition: all 0.3s linear 0s;
  292. -ms-transition: all 0.3s linear 0s;
  293. -o-transition: all 0.3s linear 0s;
  294. transition: all 0.3s linear 0s;
  295. }
  296.  
  297. input:hover,
  298. button:hover {
  299. color: rgba(0, 0, 0, 0.7);
  300. background-color: #e4e6eb;
  301. }
  302.  
  303. label[for=searchByProblemCheckbox] {
  304. margin-top: 20px !important;
  305. color: rgba(0, 0, 0, 0.5);
  306. }
  307.  
  308. .notice {
  309. margin-top: 10px !important;
  310. }
  311.  
  312. .highlighted-row td,
  313. .highlighted-row th {
  314. background-color: rgba(221, 238, 255, 0.47) !important;
  315. }
  316.  
  317. input[name=sourceFile] {
  318. border-style: dashed;
  319. border-width: 2px;
  320. border-color: #e4e6eb;
  321. border-radius: 10px;
  322. padding: 5px;
  323. width: 100%;
  324. }
  325.  
  326. .submit-form {
  327. margin-top: 20px;
  328. background-color: #fff;
  329. padding: 20px 0 20px 0;
  330. border-radius: 10px;
  331. -webkit-transition: all 0.3s linear 0s;
  332. -moz-transition: all 0.3s linear 0s;
  333. -ms-transition: all 0.3s linear 0s;
  334. -o-transition: all 0.3s linear 0s;
  335. transition: all 0.3s linear 0s;
  336. }
  337.  
  338. .submit-form:hover {
  339. -webkit-box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  340. -moz-box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  341. box-shadow: 0px 1px 15px 0px rgba(0, 0, 0, 0.1);
  342. }
  343.  
  344. .source-popup pre {
  345. padding: 10px;
  346. border-style: solid;
  347. border-width: 2px;
  348. border-color: #e4e6eb;
  349. }
  350.  
  351. hr {
  352. border: 0;
  353. height: 2px;
  354. background-image: linear-gradient(to right, rgba(228, 230, 235, 0.1), rgba(228, 230, 235, 1), rgba(228, 230, 235, 0.1));
  355. }
  356.  
  357. .popup-input-div div,
  358. .popup-output-div div,
  359. .popup-answer-div div,
  360. .popup-checker-div div {
  361. margin-top: 10px;
  362. margin-bottom: 5px;
  363. }
  364.  
  365. .table-form {
  366. padding: 10px;
  367. }
  368. .diff-notifier {
  369. display: none !important;
  370. }
  371. /*main*/
  372. .problemindexholder {
  373. box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;
  374. margin-top: 10px;
  375. background-color: #fff;
  376. padding: 30px;
  377. border-radius: 10px;
  378. -webkit-transition: all 0.3s linear 0s;
  379. -moz-transition: all 0.3s linear 0s;
  380. -ms-transition: all 0.3s linear 0s;
  381. -o-transition: all 0.3s linear 0s;
  382. transition: all 0.3s linear 0s;
  383. }
  384.  
  385. .sample-test {
  386. margin-top: 10px;
  387. }
  388.  
  389. .sample-test .input .title,
  390. .sample-test .output .title {
  391. font-size: 15px;
  392. }
  393.  
  394. .sample-test pre {
  395. padding-top: 10px !important;
  396. padding-bottom: 10px !important;
  397. padding-left: 5px !important;
  398. padding-right: 5px !important;
  399. }
  400.  
  401. .placeholder {
  402. margin-bottom: 10px !important;
  403. }
  404.  
  405. a[href^="/passwordRecovery"] {
  406. display: block;
  407. margin-top: 20px !important;
  408. }
  409.  
  410. .backLava {
  411. border-radius: 10px;
  412. }
  413.  
  414. #body {
  415. max-width: 1220px;
  416. min-width: 980px;
  417. }
  418.  
  419. ::selection {
  420. background-color: #c4b5fd!important;
  421. color: #000!important;
  422. }
  423.  
  424. ::-webkit-scrollbar-thumb {
  425. background: #323536!important;
  426. }
  427. ::-webkit-scrollbar {
  428. width: 10px;
  429. height: 10px;
  430. }
  431. div.ttypography a:hover {
  432. color: #9e88f5 !important;
  433. background: #cfecdc;
  434. }
  435. div.ttypography li,
  436. div.ttypography p {
  437. font-size: 1.1em;
  438. line-height: 1.4em;
  439. }
  440. /** Footer custom */
  441. #footer {
  442. /** background-color: #fff;
  443. width: 100%;
  444. height: 100%;
  445. border-top-left-radius: 20px;
  446. border-top-right-radius: 20px;
  447. border-top-color: #e4e6eb;
  448. **/
  449. display: none !important;
  450. }
  451. pre {
  452. tab-size: 4;
  453. }
  454.  
  455. .sidebar-menu ul {
  456. font-size: 1.4rem;
  457. }
  458. /** move pos **/
  459. #header {
  460. position: absolute !important;
  461. top: 20px;
  462. z-index: 1;
  463. right: 20px;
  464. /* 将元素右对齐 */
  465. width: 220px;
  466. background: #00000000;
  467. }
  468. .menu-box {
  469. background: #00000000;
  470. width: 70%;
  471. }
  472. .property-title,
  473. #header > div:nth-child(1) {
  474. display: none !important;
  475. }
  476. /** info remove to bottom */
  477. .time-limit {
  478. position: fixed !important;
  479. right: 30px;
  480. bottom: 70px;
  481. z-index: -9;
  482. }
  483. .memory-limit {
  484. position: fixed !important;
  485. right: 30px;
  486. bottom: 50px;
  487. z-index: -9;
  488.  
  489. }
  490. .input-file {
  491. position: fixed !important;
  492. right: 30px;
  493. bottom: 30px;
  494. z-index: -9;
  495. }
  496. .output-file {
  497. position: fixed !important;
  498. right: 30px;
  499. bottom: 10px;
  500. z-index: -9;
  501. }
  502. body {
  503. zoom: 111% !important;
  504. }
  505. `;
  506. styleTag.appendChild(document.createTextNode(cssRules));
  507. document.head.appendChild(styleTag);
  508. };
  509. const codeforces_luogu = () => {
  510. function getProblemId(str) {
  511. let pos = str.indexOf("contest/") + "contest/".length;
  512. let contestNum = "";
  513. while (str[pos] >= '0' && str[pos] <= '9') {
  514. contestNum += str[pos];
  515. pos++;
  516. }
  517. return contestNum;
  518. }
  519. function getProblemChar(str) {
  520. let pos = str.indexOf("problem/") + "problem/".length;
  521. let problemLetter = str.substr(pos);
  522. return problemLetter;
  523. }
  524. // jump to luogu.com 跳转到洛谷 delete luogu
  525. let str = window.location.href
  526. let problemId = getProblemId(str);
  527. let problemChar = getProblemChar(str);
  528. let luogulink = document.createElement('li');
  529. luogulink.setAttribute('style', 'color: green !important;');
  530. luogulink.innerHTML = `<a href="https://www.luogu.com.cn/problem/CF${problemId}${problemChar}" target="_blank"> 洛谷 </a>`;
  531. luogulink.classList.add('luogulink')
  532. document.querySelector("#sidebar > div.roundbox.sidebox.sidebar-menu.borderTopRound > ul").appendChild(luogulink)
  533. };
  534. const codeforces_friend_status = () => {
  535. // friends-status-button 好友提交历史记录
  536. let uuuuuuuuurl = window.location;
  537. let cccontestId = uuuuuuuuurl.toString().split("/").filter((x) => {
  538. if (typeof x !== 'string') { return; }
  539. const num = Number(x);
  540. if (Number.isInteger(num)) { return num; }
  541. })[0];
  542. let s = uuuuuuuuurl.toString().split("/");
  543. let iiid = s[s.length - 1];
  544. let friendBtn = document.createElement('li');
  545. friendBtn.innerHTML = `<a href="https://codeforces.com/contest/${cccontestId}/status/${iiid}?friends=on" target="_blank">Friends Status</a>`;
  546. friendBtn.classList.add('friendBtn')
  547. document.querySelector(".second-level-menu-list").appendChild(friendBtn);
  548. };
  549. const codeforces_timeLimits = () => {
  550. // time limits part 时间限制等 放到一个位置
  551. /* const timeLimits = document.querySelector(".time-limit");
  552. const memoryLimits = document.querySelector(".memory-limit");
  553. const inputLimits = document.querySelector(".input-file");
  554. const outputLimits = document.querySelector(".output-file");
  555. let informationSpace = document.querySelector();
  556. informationSpace.parentNode.insertBefore(informationSpace, info); */
  557. //informationSpace.appendChild(timeLimits);
  558. //informationSpace.appendChild(memoryLimits);
  559. //informationSpace.appendChild(inputLimits);
  560. //informationSpace.appendChild(outputLimits);
  561. };
  562. const KEY_PREFIX = 'funcdfs';
  563. const atcoder_navigation = () => {
  564. const contest = location.href.match(/^https:\/\/atcoder\.jp\/contests\/([^\/?]+)/)[1];
  565. const key = KEY_PREFIX + 'atcoder-' + contest;
  566. if (location.href.match(/^https:\/\/atcoder\.jp\/contests\/([^\/]+)\/tasks\/?$/)) {
  567. const problems = [];
  568. const rows = document.querySelectorAll('tbody>tr');
  569. for (let i = 0; i < rows.length; i++) {
  570. const links = rows[i].querySelectorAll('a');
  571. const href = links[0].getAttribute('href');
  572. const text = links[0].textContent + ' - ' + links[1].textContent;
  573. problems.push({
  574. href: href,
  575. text: text
  576. });
  577. }
  578. localStorage[key] = JSON.stringify(problems);
  579. }
  580. if (key in localStorage) {
  581. let problems = JSON.parse(localStorage[key]);
  582. const problemsBar = document.createElement('ul');
  583. problemsBar.className = 'nav nav-tabs';
  584. for (let i = 0; i < problems.length; i++) {
  585. const link = document.createElement('a');
  586. link.setAttribute('style', 'margin-left: 10px; margin-right: 10px; white-space: nowrap');
  587. link.setAttribute('href', problems[i].href);
  588. link.textContent = problems[i].text;
  589. const span = document.createElement('span');
  590. span.textContent = ' ';
  591. span.appendChild(link);
  592. problemsBar.appendChild(span);
  593. }
  594. document.getElementById('contest-nav-tabs').appendChild(problemsBar);
  595. }
  596. };
  597.  
  598. const codeforces_navigation = () => {
  599. const contest = location.href.match(/^https:\/\/codeforces\.com\/contest\/([^\/?]+)/)[1];
  600. const key = KEY_PREFIX + 'codeforces-' + contest;
  601. if (location.href.match(/^https:\/\/codeforces\.com\/contest\/([^\/]+)\/?$/)) {
  602. const problems = [];
  603. const rows = document.querySelectorAll('.problems>tbody>tr');
  604. for (let i = 1; i < rows.length; i++) {
  605. const links = rows[i].querySelectorAll('a');
  606. const href = links[0].getAttribute('href');
  607. const text = links[0].textContent.trim() + '. ' + links[1].textContent;
  608. problems.push({
  609. href: href,
  610. text: text
  611. });
  612. }
  613. localStorage[key] = JSON.stringify(problems);
  614. }
  615.  
  616. if (key in localStorage) {
  617. let problems = JSON.parse(localStorage[key]);
  618. const problemsBar = document.createElement('ul');
  619. problemsBar.setAttribute('style', 'margin-left: 15px; margin-right: 280px; padding-top: 30px');
  620. for (let i = 0; i < problems.length; i++) {
  621. const link = document.createElement('a');
  622. link.setAttribute('style', 'margin-right: 20px; white-space: nowrap');
  623. link.setAttribute('href', problems[i].href);
  624. link.textContent = problems[i].text;
  625. const span = document.createElement('span');
  626. span.textContent = ' ';
  627. span.appendChild(link);
  628. problemsBar.appendChild(span);
  629. }
  630.  
  631. const content = document.getElementById('pageContent');
  632. content.parentNode.insertBefore(problemsBar, content);
  633. }
  634. };
  635. if (location.href.match(/^https:\/\/atcoder\.jp\/contests\//)) {
  636. atcoder_navigation();
  637. } else {
  638. if (location.href.match(/^https:\/\/codeforces\.com\/contest\//)) {
  639. codeforces_navigation();
  640. }
  641. codeforces_css();
  642. codeforces_luogu();
  643. codeforces_friend_status();
  644. codeforces_timeLimits();
  645. }
  646. })();