AtCoder-Style-Changer

AtCoderのテーマをダークテーマに変更します

As of 2021-07-28. See the latest version.

  1. // ==UserScript==
  2. // @name AtCoder-Style-Changer
  3. // @namespace http://github.com/i-708
  4. // @version 1.0.0
  5. // @description AtCoderのテーマをダークテーマに変更します
  6. // @author i-708
  7. // @license MIT
  8. // @match https://atcoder.jp/*
  9. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. const baseColor = "#c3c3c3";
  14. const bgColor = "black";
  15. const borderColor = "#d10000";
  16.  
  17. // 順位表などの設定
  18. function rankingTableUpdate() {
  19. $("#btn-reset").css({
  20. color: baseColor,
  21. background: bgColor,
  22. });
  23.  
  24. $("#input-affiliation").css({
  25. color: baseColor,
  26. background: bgColor,
  27. });
  28.  
  29. $("#input-user").css("cssText", "color: #c3c3c3; background: black");
  30.  
  31. $("#select2-standings-select-country-container").css({
  32. color: baseColor,
  33. background: bgColor,
  34. border: "white 1px solid"
  35. });
  36.  
  37. $("#refresh, #auto-refresh").css({
  38. color: baseColor,
  39. background: bgColor,
  40. });
  41.  
  42. $("#standings-panel-heading.panel-heading").css({
  43. color: baseColor,
  44. background: bgColor,
  45. });
  46.  
  47. $(".btn-text").css({
  48. color: baseColor,
  49. });
  50.  
  51. $("tr").css({
  52. color: baseColor,
  53. background: bgColor,
  54. });
  55.  
  56. $("tr.info td").css({
  57. color: baseColor,
  58. background: bgColor,
  59. });
  60.  
  61. $(".standings-score").css({
  62. color: "#4aabff",
  63. });
  64.  
  65. $(".pagination.pagination-sm.mt-0.mb-1 a").css({
  66. color: baseColor,
  67. background: bgColor,
  68. "border-color": "",
  69. });
  70.  
  71. $("li.active a").css({
  72. "border-color": borderColor,
  73. });
  74.  
  75. $("td.standings-result.standings-perf").css({
  76. color: baseColor,
  77. background: bgColor,
  78. });
  79.  
  80. $("td.standings-result.standings-rate").css({
  81. color: baseColor,
  82. background: bgColor,
  83. });
  84.  
  85. $(".standings-ac").css({
  86. color: "#00e152",
  87. });
  88.  
  89. $(".standings-result p").css({
  90. color: "#d8d8d8",
  91. });
  92.  
  93. $(".standings-statistics td p,.standings-fa td p").css({
  94. color: "#d8d8d8",
  95. });
  96.  
  97. $(".sort-th.no-break a").css({
  98. color: "#d6d6d6",
  99. });
  100.  
  101. }
  102.  
  103. // userのカラー設定
  104. function userColor() {
  105. $("head").append(
  106. "<style type='text/css'> .user-blue {color: #0095ff; } </style>"
  107. );
  108.  
  109. $("head").append(
  110. "<style type='text/css'> .user-unrated {color: white; } </style>"
  111. );
  112.  
  113. $("head").append(
  114. "<style type='text/css'> .user-brown {color: #b16c28; } </style>"
  115. );
  116.  
  117. $("head").append(
  118. "<style type='text/css'> .user-green {color: #00ce00; } </style>"
  119. );
  120.  
  121. $("head").append(
  122. "<style type='text/css'> .user-gray {color: #a9a9a9; } </style>"
  123. );
  124.  
  125. $("head").append(
  126. "<style type='text/css'> .user-yellow {color: #dede01; } </style>"
  127. );
  128.  
  129. $("head").append(
  130. "<style type='text/css'> .user-cyan {color: #00f1f1; } </style>"
  131. );
  132. }
  133. // 監視
  134. function loadObservation() {
  135. const loadElem = document.getElementById("vue-standings").getElementsByClassName("loading-show")[0];
  136. const loadOptions = { attributes: true };
  137. const loadObserver = new MutationObserver(() => {
  138. if (!!document.getElementById("standings-tbody")) {
  139. rankingTableUpdate();
  140. standObservation();
  141. refreshObservation()
  142. };
  143. });
  144. loadObserver.observe(loadElem, loadOptions);
  145. }
  146.  
  147. function standObservation() {
  148. const standElem = document.getElementById("standings-tbody");
  149. const standElemOption = {
  150. childList: true,
  151. attributes: true,
  152. };
  153. if (standElem) {
  154. const standObserver = new MutationObserver(rankingTableUpdate);
  155. standObserver.observe(standElem, standElemOption);
  156. }
  157. }
  158.  
  159. function refreshObservation() {
  160. const refreshElem = document.getElementById("refresh");
  161. const refreshElemOptions = {
  162. attributes: true,
  163. attributeFilter: ["class"],
  164. };
  165. if (refreshElem) {
  166. const refreshObserver = new MutationObserver((mutationRecord) => {
  167. const isDisabled = mutationRecord[0].target.classList.contains("disabled");
  168. if (isDisabled) {
  169. rankingTableUpdate();
  170. }
  171. }).observe(refreshElem, refreshElemOptions);
  172. };
  173. }
  174. function resultObservation() {
  175. const resultElem = document.getElementsByClassName("pagination pagination-sm mt-0 mb-1")[0]
  176. const resultOptions = {
  177. childList: true,
  178. attributes: true
  179. };
  180. const resultObserver = new MutationObserver(rankingTableUpdate).observe(resultElem, resultOptions);
  181. }
  182.  
  183. function init() {
  184.  
  185. //全体共通
  186. $("li.active a").not('ul.dropdown-menu li a').css({
  187. "border-color": borderColor,
  188. "border": " #d10000 solid 1px"
  189. });
  190.  
  191. $(".btn-primary").css({
  192. "border-color": borderColor,
  193. });
  194.  
  195. // タイマー
  196. $("#fixed-server-timer").css({
  197. color: bgColor,
  198. });
  199.  
  200. $("head").append(
  201. "<style type='text/css'> #header .header-page li.is-active a {color: #c3c3c3 !important; } </style>"
  202. );
  203.  
  204. $("head").append(
  205. "<style type='text/css'> #header .header-lang li a:hover {color: #c3c3c3 !important; } </style>"
  206. );
  207.  
  208. //ユーザーカラー
  209. userColor();
  210.  
  211. // ユーザページ
  212. $("body").css({
  213. "background-color": bgColor,
  214. color: baseColor,
  215. });
  216.  
  217. $("#main-container").css({
  218. "background-color": bgColor,
  219. });
  220.  
  221. $("button").css({
  222. color: baseColor,
  223. "background-color": bgColor,
  224. });
  225.  
  226. $(".btn.btn-default.active").css({
  227. "border-color": borderColor,
  228. });
  229.  
  230. $("ul").css({
  231. color: baseColor,
  232. "background-color": bgColor,
  233. });
  234.  
  235. $("head").append(
  236. "<style type='text/css'> .new-is-active {color: '#c3c3c3'; } </style>"
  237. );
  238.  
  239. $(".glyphicon.glyphicon-resize-full, .glyphicon.glyphicon-search.black").css({
  240. color: baseColor,
  241. });
  242.  
  243. $(".form-control.input-sm").css({
  244. color: baseColor,
  245. "background-color": bgColor,
  246. });
  247.  
  248. $(".header-inner").css({
  249. "background-color": bgColor,
  250. "border-bottom-color": baseColor,
  251. });
  252.  
  253. $(".header-sub_page").css({
  254. "background-color": bgColor,
  255. });
  256. $("#footer").css({
  257. background: bgColor,
  258. });
  259.  
  260. $(".t-inner").css({
  261. "background-color": bgColor,
  262. });
  263.  
  264. $(".text-center.even").css({
  265. "background-color": bgColor,
  266. });
  267.  
  268. $(".text-center.odd").css({
  269. "background-color": bgColor,
  270. });
  271.  
  272. $("a").css({
  273. color: baseColor,
  274. "background-color": "transparent",
  275. });
  276.  
  277. // コンテスト成績証
  278. $(".panel-body").css({
  279. "background-color": bgColor,
  280. });
  281.  
  282. $(".panel-footer").css({
  283. "background-color": bgColor,
  284. });
  285.  
  286. $("tr").css({
  287. color: baseColor,
  288. });
  289.  
  290. $(".grey").css({
  291. color: "#f2f1f1",
  292. });
  293.  
  294. $(".dark-grey").css({
  295. color: "#ddd",
  296. });
  297.  
  298. $(".panel-primary").css({
  299. "border-color": borderColor,
  300. });
  301.  
  302. $(".panel-primary>.panel-heading").css({
  303. "border-color": borderColor,
  304. });
  305.  
  306. //コンテストページ
  307. $("tr").css({
  308. "background-color": bgColor,
  309. });
  310.  
  311. $("#contest-nav-tabs").css({
  312. "background-color": bgColor,
  313. });
  314.  
  315. $("li.active a").css({
  316. "background-color": bgColor,
  317. });
  318.  
  319. $(".insert-participant-box").css({
  320. "background-color": bgColor,
  321. });
  322.  
  323. $(".container-fluid").css({
  324. "background-color": bgColor,
  325. });
  326.  
  327. $("#main-div").css({
  328. background: bgColor,
  329. });
  330.  
  331. $("small.contest-duration, span.mr-2").css({
  332. color: baseColor,
  333. });
  334.  
  335. // 問題ページ
  336. $("pre").css({
  337. color: baseColor,
  338. background: bgColor,
  339. });
  340.  
  341. $(".btn-copy").css({
  342. color: baseColor,
  343. background: bgColor,
  344. });
  345.  
  346. $("span.select2-selection.select2-selection--single").css({
  347. color: baseColor,
  348. background: bgColor,
  349. });
  350.  
  351. $("span.select2-selection__rendered").css({
  352. color: baseColor,
  353. background: bgColor,
  354. });
  355.  
  356. $("code:not([class])").css({
  357. color: "#ffaa2a",
  358. "background-color": "transparent",
  359. border: "white solid 1px",
  360. });
  361. $(".alert.alert-warning.alert-dismissible.fade.in").css({
  362. color: "#ffbe2b",
  363. "background-color": bgColor,
  364. border: "#ffdd38 solid 1px",
  365. });
  366.  
  367. /* コード画面*/
  368. $(".CodeMirror-scroll").css({
  369. "background-color": bgColor,
  370. });
  371.  
  372. // カーソル
  373. $("head").append(
  374. "<style type='text/css'>.CodeMirror-cursor{border-left: 1px solid white;border-right: none;width: 0;}</style>"
  375. );
  376.  
  377. // 文字色
  378. $("head").append("<style type='text/css'>.cm-s-default .cm-builtin{color: #bb98ff}</style>");
  379.  
  380. $("head").append("<style type='text/css'>.cm-s-default .cm-keyword{color: #ed72ff}</style>");
  381.  
  382. $("head").append("<style type='text/css'>.cm-s-default .cm-def{color: #23c2ff}</style>");
  383.  
  384. $("head").append("<style type='text/css'>.cm-s-default .cm-string{color: #ff9a5f}</style>");
  385.  
  386. $("head").append("<style type='text/css'>.cm-s-default .cm-number{color: #11cb81}</style>");
  387.  
  388. $("head").append("<style type='text/css'>.cm-s-default .cm-comment{color: #9e9e9e}</style>");
  389.  
  390. $(".CodeMirror-gutter").css({
  391. color: "white",
  392. "background-color": bgColor,
  393. });
  394.  
  395. $("head").append("<style type='text/css'>div.CodeMirror-linenumber.CodeMirror-gutter-elt{color: white}</style>");
  396.  
  397. $(".CodeMirror").css("color", "white");
  398.  
  399. //提出結果
  400. $(".panel-heading").css({
  401. color: baseColor,
  402. background: bgColor,
  403. });
  404.  
  405. $(".label-warning").css({
  406. background: "#d58617",
  407. });
  408.  
  409. $(".btn.btn-link.btn-xs").css({
  410. color: baseColor,
  411. background: bgColor,
  412. border: "solid 1px",
  413. });
  414.  
  415. //コードテスト
  416. $("head").append(
  417. "<style type='text/css'>.table>thead>tr>td.danger, .table>tbody>tr>td.danger, .table>tfoot>tr>td.danger, .table>thead>tr>th.danger, .table>tbody>tr>th.danger, .table>tfoot>tr>th.danger, .table>thead>tr.danger>td, .table>tbody>tr.danger>td, .table>tfoot>tr.danger>td, .table>thead>tr.danger>th, .table>tbody>tr.danger>th, .table>tfoot>tr.danger>th{background-color: #a31010; color: #c3c3c3;}</style>"
  418. );
  419.  
  420. $("head").append(
  421. "<style type='text/css'>table.table.table-bordered tbody{color:#c3c3c3; background-color: black;}</style>"
  422. );
  423.  
  424. $("head").append(
  425. "<style type='text/css'>table>thead>tr>td.success, .table>tbody>tr>td.success, .table>tfoot>tr>td.success, .table>thead>tr>th.success, .table>tbody>tr>th.success, .table>tfoot>tr>th.success, .table>thead>tr.success>td, .table>tbody>tr.success>td, .table>tfoot>tr.success>td, .table>thead>tr.success>th, .table>tbody>tr.success>th, .table>tfoot>tr.success>th{color:#c3c3c3; background-color: #379d0d;}</style>"
  426. );
  427.  
  428. $("head").append(
  429. "<style type='text/css'>.btn-primary{color:#c3c3c3 !important; background-color: black !important; border-color: #d10000 !important;}</style>"
  430. );
  431.  
  432. $("textarea#input.form-control.customtest-textarea").css({
  433. color: "white",
  434. background: bgColor,
  435. });
  436.  
  437. $("textarea#stdout.form-control.customtest-textarea").css({
  438. color: "white",
  439. background: bgColor,
  440. });
  441.  
  442. $("textarea#stderr.form-control.customtest-textarea").css({
  443. color: "white",
  444. background: bgColor,
  445. });
  446.  
  447. // Home
  448. $("div.f-flex.f-flex_mg5.f-flex_mg0_s.f-flex_mb5_s div.f-flex4.f-flex12_s").css({
  449. border: "solid 1px",
  450. });
  451.  
  452. $("head").append(
  453. "<style type='text/css'>#header .header-page li a:hover{color:#c3c3c3 !important;}</style>"
  454. );
  455.  
  456. $("head").append(
  457. "<style type='text/css'>#header .header-page li a:before{content: '';width: 0;height: 2px;position: absolute;left: 0;right: 0;bottom: 0;background-color: white !important;-webkit-transition: width .4s;transition: width .4s;}</style>"
  458. );
  459.  
  460. $(".m-box_inner").css({
  461. "background-color": bgColor,
  462. });
  463.  
  464. $(".m-box-news_post::before").css({
  465. "background-color": bgColor,
  466. });
  467.  
  468. $("a.a-btn_bg.small").css({
  469. color: baseColor,
  470. "background-color": bgColor,
  471. });
  472.  
  473. $(".panel.panel-primary").css({
  474. color: baseColor,
  475. "background-color": bgColor,
  476. });
  477.  
  478. $("#keyvisual").css({
  479. color: baseColor,
  480. "background-color": bgColor,
  481. "background-blend-mode": "darken",
  482. });
  483. $("head").append(
  484. "<style type='text/css'>#keyvisual .keyvisual-inner:before{background-color:black; content: ''; display: block;position: absolute;top: 0;width: 18px;height: 400px;pointer-events: none;}</style>"
  485. );
  486.  
  487. $("head").append(
  488. "<style type='text/css'>.m-box-news_post:before{content: '';position: absolute;left: 0;bottom: 0;width: 100%;height: 100px;background: -webkit-gradient(linear, left bottom, left top, color-stop(50%, #fff), to(rgba(255,255,255,0)));background: linear-gradient(0deg, #000 50%, rgba(255,255,255,0) 100%);}</style>"
  489. );
  490.  
  491. $(".status").css({
  492. "background-color": "#037abf",
  493. });
  494.  
  495. $(".status.status-gray").css({
  496. "background-color": "#717171",
  497. });
  498.  
  499. $(".status.status-green").css({
  500. "background-color": "#317f01",
  501. });
  502.  
  503. $(".a-btn_bg").css({
  504. border: "solid 1px",
  505. });
  506.  
  507. $(".a-btn_arrow").css({
  508. color: baseColor,
  509. "background-color": bgColor,
  510. });
  511.  
  512. $(".a-btn_arrow").css({
  513. "cssText": $(".a-btn_arrow").attr("style") + "color: #c3c3c3 !important;"
  514. });
  515.  
  516. //PAST
  517. $(".center-block").css({
  518. "background-color": "#d6d6d6",
  519. });
  520.  
  521. //Jobs
  522. $(".f-flex3").css({
  523. border: "solid 1px",
  524. });
  525.  
  526. $(".m-list-job_company").css({
  527. color: baseColor,
  528. });
  529.  
  530. //順位表
  531. $("head").append(
  532. "<style type='text/css'>tr.info td{background-color: black !important;color: #c3c3c3 !important;}</style>"
  533. );
  534.  
  535. //ランキング
  536. $(".form-control").css({
  537. color: baseColor,
  538. "background-color": bgColor,
  539. });
  540. }
  541.  
  542. init();
  543.  
  544. // 監視
  545. if (document.URL.match("/standings")) {
  546. loadObservation();
  547. }
  548.  
  549. if (document.URL.match("/results")) {
  550. resultObservation();
  551. }
  552.  
  553. // 色変えコードの埋め込み
  554. const locationPathName = location.pathname
  555. const correctLocation = location.pathname.match(/\/users\/[A-Za-z0-9_]*/)
  556. if (locationPathName == correctLocation && (location.search == "" || location.search == "?graph=rank" || location.search == "?graph=rating")) {
  557. $("head").append(
  558. `<script>
  559. function pixelDataChange(event) {
  560. var c = document.getElementById("ratingStatus");
  561. if (!c){
  562. c = document.getElementById("rankStatus");
  563. }
  564. const canvas = c;
  565. const ctx = canvas.getContext("2d");
  566. const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  567. const data = imageData.data;
  568. const oldColor = [
  569. [128,128,128],
  570. [128,64,0],
  571. [0,128,0],
  572. [0,192,192],
  573. [0,0,255],
  574. [192,192,0],
  575. [255,128,0],
  576. [255,0,0],
  577. [226,83,14],
  578. [192,192,192],
  579. [254,195,11],
  580. [132,230,255]
  581. ];
  582. const newColor = [
  583. [201,201,201],
  584. [168,85,2],
  585. [2,186,2],
  586. [0,192,192],
  587. [24,148,255],
  588. [192,192,0],
  589. [255,128,0],
  590. [255,0,0],
  591. [226,83,14],
  592. [192,192,192],
  593. [254,195,11],
  594. [132,230,255]
  595. ];
  596. let result = newColor.length;
  597. let jPlus = 0;
  598. if (location.search == "?graph=rank" || !!document.getElementById("rankStatus")){
  599. jPlus = 8;
  600. }
  601. for (let i = 0, len = data.length; i < len; i += 4) {
  602. for (let j = jPlus; j < oldColor.length; j += 1) {
  603. if (data[i] == oldColor[j][0] && data[i + 1] == oldColor[j][1] && data[i + 2] == oldColor[j][2]) {
  604. result = j;
  605. break;
  606. }
  607. }
  608. if (result < newColor.length) {
  609. data[i] = newColor[result][0];
  610. data[i + 1] = newColor[result][1];
  611. data[i + 2] = newColor[result][2];
  612. }
  613. else{
  614. data[i] = 255;
  615. data[i + 1] = 255;
  616. data[i + 2] = 255;
  617. }
  618. }
  619. imageData.data = data;
  620. ctx.putImageData(imageData, 0, 0);
  621. }
  622. </script>`
  623. );
  624. $(".mt-2.mb-2").append(
  625. `<script>
  626. window.onload = function(){
  627. createjs.Ticker.addEventListener("tick", pixelDataChange);
  628. };
  629. </script>`
  630. );
  631. }
  632. })();