您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
AtCoderの提出結果一覧画面に自動検索機能などを追加します。
当前为
- // ==UserScript==
- // @name AtCoder ResultsPage Tweaks
- // @namespace https://github.com/yukuse
- // @version 1.0.0
- // @description AtCoderの提出結果一覧画面に自動検索機能などを追加します。
- // @author yukuse
- // @include https://atcoder.jp/contests/*/submissions*
- // @grant none
- // @license MIT
- // @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/locale/ja.min.js
- // ==/UserScript==
- /* global jQuery moment */
- jQuery(function ($) {
- const options = {
- // 検索条件変更時に自動検索 on/off
- autoSearchOnChange: true,
- // 検索結果の動的読み込み on/off
- dynamicResult: true,
- // 検索条件変更時のフォーカス維持 on/off
- keepSelectFocus: true,
- lang: 'ja',
- };
- // 読み込み元と整合性を取る
- // https://wiki.greasespot.net/Third-Party_Libraries
- this.$ = this.jQuery = jQuery.noConflict(true);
- moment.locale(options.lang);
- const $container = $('#main-container');
- const $panelSubmission = $container.find('.panel-submission');
- /**
- * from: js/base.js
- */
- function fixTime() {
- $('time.fixtime').each(function _() {
- const date = moment($(this).text());
- if ($(this).hasClass('fixtime-second')) {
- $(this).text(date.format('YYYY-MM-DD HH:mm:ss'));
- } else if ($(this).hasClass('fixtime-short')) {
- $(this).text(date.format('M/D(ddd) HH:mm'));
- } else {
- $(this).text(date.format('YYYY-MM-DD(ddd) HH:mm'));
- }
- $(this).removeClass('fixtime');
- });
- }
- const baseParams = {
- 'f.Task': '',
- 'f.LanguageName': '',
- 'f.Status': '',
- 'f.User': '',
- page: 1,
- };
- function parseSubmissionsUrl(url) {
- const params = { ...baseParams };
- if (url) {
- Object.keys(params).forEach((key) => {
- const regexp = new RegExp(`${key}=([^&]+)`);
- const result = url.match(regexp);
- if (result) {
- [, params[key]] = result;
- }
- });
- }
- return params;
- }
- /**
- * valueの変化を監視する関数
- */
- const watch = (() => {
- const watchers = [];
- setInterval(() => {
- watchers.forEach((watcher) => {
- const { prevValue, el, onChange } = watcher;
- if (el.value !== prevValue) {
- watcher.prevValue = el.value;
- onChange(el.value, prevValue);
- }
- });
- }, 50);
- return (el, onChange) => {
- watchers.push({
- prevValue: el.value,
- el,
- onChange,
- });
- };
- })();
- /**
- * 現在のURLに応じて検索結果表示を更新
- * TODO: ジャッジ中表示対応
- */
- function updateSearchResult() {
- const { href } = location;
- const params = parseSubmissionsUrl(href);
- // 検索条件を遷移先の状態にする
- // FIXME: ページ遷移によりselectの状態が切り替わったとき、selectの表示が元のままになる
- Object.keys(params).forEach((key) => {
- $panelSubmission.find(`[name="${key}"]`).val(params[key]).trigger('change');
- });
- const $tmp = $('<div>');
- $tmp.load(`${href} #main-container`, '', () => {
- const $newTable = $tmp.find('.table-responsive, .panel-body');
- // テーブル置換
- $panelSubmission.find('.table-responsive, .panel-body').replaceWith($newTable);
- // ページネーション置換
- if ($newTable.hasClass('table-responsive')) {
- $container.find('.pagination').replaceWith($tmp.find('.pagination:first'));
- } else {
- $container.find('.pagination').empty();
- }
- // 日付を表示
- fixTime();
- });
- }
- /**
- * 検索条件を元にURLを更新し、結果を表示する
- */
- function showSearchResult(params) {
- const paramsStr = Object.keys(params).map((key) => `${key}=${params[key]}`).join('&');
- const url = `${location.pathname}?${paramsStr}`;
- if (options.dynamicResult) {
- history.pushState({}, '', url);
- updateSearchResult();
- } else {
- location.href = url;
- }
- }
- /**
- * 選択時にフォーカスが残るようにする
- */
- function initSelectTweaks() {
- $panelSubmission.find('#select-task, #select-language, #select-status').each((_, el) => {
- watch(el, () => {
- // 選択時に自動検索
- if (options.autoSearchOnChange) {
- const params = { ...baseParams };
- Object.keys(params).forEach((key) => {
- params[key] = $panelSubmission.find(`[name="${key}"]`).val();
- });
- params.page = 1;
- showSearchResult(params);
- }
- // 選択時にフォーカスが飛ばないようにする
- if (options.keepSelectFocus) {
- el.focus();
- }
- });
- });
- }
- const urlRegExp = new RegExp(location.pathname);
- /**
- * 検索結果のリンククリック時のページ遷移をなくし、表示を動的に更新する処理に置き換え
- */
- function initLinks() {
- $container.on('click', '.pagination a, .panel-submission a', (event) => {
- const { href } = event.target;
- if (!urlRegExp.test(href)) {
- return;
- }
- event.preventDefault();
- showSearchResult(parseSubmissionsUrl(href));
- });
- }
- function init() {
- initSelectTweaks();
- if (options.dynamicResult) {
- window.addEventListener('popstate', updateSearchResult);
- initLinks();
- }
- }
- init();
- });
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址