您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
順位表の得点をダブルクリックすると、該当するコンテスタントの実装を見ることができます。
- // ==UserScript==
- // @name AtCoder Jump to Submissions from Standings
- // @namespace http://tampermonkey.net/
- // @version 0.2
- // @description 順位表の得点をダブルクリックすると、該当するコンテスタントの実装を見ることができます。
- // @match https://atcoder.jp/contests/*/standings*
- // @require https://code.jquery.com/jquery-3.6.1.min.js
- // @author hiro_hiro
- // @license CC0
- // @supportURL https://github.com/KATO-Hiro/AtCoder-Jump-to-Submissions-from-Standings/issues
- // @grant none
- // ==/UserScript==
- $(function () {
- 'use strict';
- $(document).on('dblclick', '.standings-result', function () {
- const $standingsType = getStandingsType($('body'));
- const $prefix = addPrefixIfNeeds($standingsType);
- const $clickedColumnIndex = getClickedColumnIndex(this, $standingsType);
- const $taskUrls = $('body').find('thead a');
- const $taskId = getTaskId($taskUrls, $clickedColumnIndex);
- const $username = getUserName(this);
- const $displayLanguage = getDisplayLanguage($(location));
- const $suffix = addSuffixIfNeeds($displayLanguage);
- // 順位表の範囲外なら、提出ページに遷移しない
- if ($clickedColumnIndex < $taskUrls.length) {
- jumpToPersonalSubmissions($prefix, $taskId, $username, $suffix);
- }
- });
- })();
- function getStandingsType(object) {
- let $standingsType = '';
- let isVirtual = $(object).find('script:contains("virtual")')[0];
- let isMultiply = $(object).find('script:contains("multiply_ranks")')[0];
- let isTeam = $(object).find('script:contains("team")')[0];
- let isExtended = $(object).find('script:contains("extended")')[0];
- // HACK: if分岐はメンテナンス的によくないかも
- // HACK: 他の言語のEnumに相当する構文がデフォルトで存在しない?
- if (isVirtual) {
- $standingsType = 'virtual';
- } else if (isMultiply) {
- $standingsType = 'multiply';
- } else if (isTeam) {
- $standingsType = 'team';
- } else if (isExtended) {
- $standingsType = 'extended';
- } else {
- $standingsType = 'general';
- }
- return $standingsType
- }
- function addPrefixIfNeeds(standingsType) {
- let prefix = '';
- if (standingsType != 'general') {
- prefix = '../';
- }
- return prefix
- }
- function getTaskId(taskUrls, clickedColumnIndex) {
- let $taskId = '';
- taskUrls.each((index) => {
- if (index == clickedColumnIndex) {
- const $url = taskUrls[index].pathname;
- const $elements = $url.split('/');
- const $length = $elements.length;
- $taskId = $elements[$length - 1]; // 0-indexed
- }
- });
- return $taskId
- }
- // HACK: 順位表の列数に応じた処理をしているため、AtCoderのUIが変更されると動かなくなる可能性がある
- // WHY : 順位表の得点の欄に、問題のIDが含まれていないため
- function getClickedColumnIndex(object, standingsType) {
- let $clickedColumnIndex = $(object)[0].cellIndex;
- // コンテスト当日の順位表と延長戦順位表・バーチャル順位表の列の並びに違いがある
- // 当日の順位表の並びに合わせる
- if (standingsType == 'virtual' || standingsType == 'extended') {
- $clickedColumnIndex -= 1
- }
- // 順位とユーザ名の欄を扱わずに済むようにインデックスを補正
- // A問題がindex = 0となるようにしている
- $clickedColumnIndex -= 3
- return $clickedColumnIndex
- }
- function getUserName(object) {
- const $standings = $(object).siblings('td');
- const $username = $standings.find('.username span').text();
- return $username
- }
- function getDisplayLanguage(location) {
- let language = 'jp';
- const params = location.attr('search');
- if (params.match(/lang=en/)) {
- language = 'en';
- }
- return language
- }
- function addSuffixIfNeeds($displayLanguage) {
- let suffix = '&lang=';
- if ($displayLanguage == 'en') {
- suffix += 'en';
- } else {
- suffix = '';
- }
- return suffix
- }
- function jumpToPersonalSubmissions(prefix, taskId, username, suffix) {
- setTimeout(function () {
- location.href = `${prefix}submissions?f.Task=${taskId}&f.Language=&f.Status=AC&f.User=${username}${suffix}`;
- }, 250)
- }