AtCoder Jump to Submissions from Standings

順位表の得点をダブルクリックすると、該当するコンテスタントの実装を見ることができます。

目前为 2020-10-14 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name AtCoder Jump to Submissions from Standings
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.1
  5. // @description 順位表の得点をダブルクリックすると、該当するコンテスタントの実装を見ることができます。
  6. // @match https://atcoder.jp/contests/*/standings*
  7. // @require https://code.jquery.com/jquery-3.4.1.min.js
  8. // @author hiro_hiro
  9. // @license CC0
  10. // @supportURL https://github.com/KATO-Hiro/AtCoder-Jump-to-Submissions-from-Standings/issues
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. $(function () {
  15. 'use strict';
  16.  
  17. $(document).on('dblclick', '.standings-result', function () {
  18. const $standingsType = getStandingsType($('body'));
  19.  
  20. const $prefix = addPrefixIfNeeds($standingsType);
  21.  
  22. const $clickedColumnIndex = getClickedColumnIndex(this, $standingsType);
  23. const $taskUrls = $('body').find('thead a');
  24. const $taskId = getTaskId($taskUrls, $clickedColumnIndex);
  25.  
  26. const $username = getUserName(this);
  27.  
  28. const $displayLanguage = getDisplayLanguage($(location));
  29. const $suffix = addSuffixIfNeeds($displayLanguage);
  30.  
  31. // 順位表の範囲外なら、提出ページに遷移しない
  32. if ($clickedColumnIndex < $taskUrls.length) {
  33. jumpToPersonalSubmissions($prefix, $taskId, $username, $suffix);
  34. }
  35. });
  36. })();
  37.  
  38. function getStandingsType(object) {
  39. let $standingsType = '';
  40. let isVirtual = $(object).find('script:contains("virtual")')[0];
  41. let isMultiply = $(object).find('script:contains("multiply_ranks")')[0];
  42. let isTeam = $(object).find('script:contains("team")')[0];
  43.  
  44. // HACK: if分岐はメンテナンス的によくないかも
  45. // HACK: 他の言語のEnumに相当する構文がデフォルトで存在しない?
  46. if (isVirtual) {
  47. $standingsType = 'virtual';
  48. } else if (isMultiply) {
  49. $standingsType = 'multiply';
  50. } else if (isTeam) {
  51. $standingsType = 'team';
  52. } else {
  53. $standingsType = 'general';
  54. }
  55.  
  56. return $standingsType
  57. }
  58.  
  59. function addPrefixIfNeeds(standingsType) {
  60. let prefix = '';
  61.  
  62. if (standingsType != 'general') {
  63. prefix = '../';
  64. }
  65.  
  66. return prefix
  67. }
  68.  
  69. function getTaskId(taskUrls, clickedColumnIndex) {
  70. let $taskId = '';
  71.  
  72. taskUrls.each((index) => {
  73. if (index == clickedColumnIndex) {
  74. const $url = taskUrls[index].pathname;
  75. const $elements = $url.split('/');
  76. const $length = $elements.length;
  77.  
  78. $taskId = $elements[$length - 1]; // 0-indexed
  79. }
  80. });
  81.  
  82. return $taskId
  83. }
  84.  
  85. // HACK: 順位表の列数に応じた処理をしているため、AtCoderのUIが変更されると動かなくなる可能性がある
  86. // WHY : 順位表の得点の欄に、問題のIDが含まれていないため
  87. function getClickedColumnIndex(object, standingsType) {
  88. let $clickedColumnIndex = $(object)[0].cellIndex;
  89.  
  90. // コンテスト当日の順位表とバーチャル順位表の列の並びに違いがある
  91. // 当日の順位表の並びに合わせる
  92. if (standingsType == 'virtual') {
  93. $clickedColumnIndex -= 1
  94. }
  95.  
  96. // 順位とユーザ名の欄を扱わずに済むようにインデックスを補正
  97. // A問題がindex = 0となるようにしている
  98. $clickedColumnIndex -= 3
  99.  
  100. return $clickedColumnIndex
  101. }
  102.  
  103. function getUserName(object) {
  104. const $standings = $(object).siblings('td');
  105. const $username = $standings.find('.username span').text();
  106.  
  107. return $username
  108. }
  109.  
  110. function getDisplayLanguage(location) {
  111. let language = 'jp';
  112. const params = location.attr('search');
  113.  
  114. if (params.match(/lang=en/)) {
  115. language = 'en';
  116. }
  117.  
  118. return language
  119. }
  120.  
  121. function addSuffixIfNeeds($displayLanguage) {
  122. let suffix = '&lang=';
  123.  
  124. if ($displayLanguage == 'en') {
  125. suffix += 'en';
  126. } else {
  127. suffix = '';
  128. }
  129.  
  130. return suffix
  131. }
  132.  
  133. function jumpToPersonalSubmissions(prefix, taskId, username, suffix) {
  134. setTimeout(function () {
  135. location.href = `${prefix}submissions?f.Task=${taskId}&f.Language=&f.Status=AC&f.User=${username}${suffix}`;
  136. }, 250)
  137. }