您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
提出言語のフィルタリングと並び替え
- // ==UserScript==
- // @name AtCoder Language Filter
- // @namespace https://github.com/morioprog
- // @version 1.0.2
- // @description 提出言語のフィルタリングと並び替え
- // @author morio_prog
- // @match *://atcoder.jp/contests/*/tasks/*
- // @match *://atcoder.jp/contests/*/submit*
- // @match *://atcoder.jp/contests/*/custom_test*
- // @license CC0
- // @require https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/js/select2.min.js
- // ==/UserScript==
- (function() {
- 'use strict';
- const DEFAULT_LANGUAGE_KEY = 'defaultLang';
- const SAVED_LANGUAGE_KEY = 'userscript-languagefilter-savedlanguage';
- function moveElementToEndOfParent($ele) {
- const parent = $ele.parent();
- $ele.detach();
- parent.append($ele);
- }
- let defLang = localStorage.getItem(DEFAULT_LANGUAGE_KEY);
- if (defLang) defLang = defLang.replace(/[^0-9]/g, '');
- const $selectLanguage = $('#select-lang select');
- /* Build language-map */
- const optMap = new Map(); // {lang: [value, data-mime]}
- $selectLanguage.children('option').each(function(_, e) {
- const $opt = $(e);
- optMap.set(
- $opt.text(),
- [
- $opt.attr('value'),
- $opt.attr('data-mime'),
- ]
- );
- $(this).remove();
- });
- /* Add button */
- const buttonHtml = `<p><button type="button" class="btn btn-default btn-sm btn-auto-height" data-toggle="modal" data-target="#LangFilterModal">提出言語の選択</button></p>`;
- $('#main-container > div.row > div > form > div > div.editor-buttons').append(buttonHtml);
- /* Add modal */
- const modalHtml = `
- <div class="modal fade" id="LangFilterModal" tabindex="-1" role="dialog" aria-labelledby="LangFilterModalLabel">
- <div class="modal-dialog" role="document">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
- <h4 class="modal-title" id="LangFilterModalLabel">提出言語の選択</h4>
- </div>
- <div class="modal-body" id="langfilter-modal">
- <select id="langfilter-select2" multiple="multiple"></select>
- </div>
- <div class="modal-footer">
- <button type="button" id="langfilter-selectall" class="btn btn-info pull-left">Select All</button>
- <button type="button" id="langfilter-clear" class="btn btn-danger pull-left">Clear</button>
- <span id="langfilter-savelabel" style="margin-right:20px;"></span>
- <button type="button" id="langfilter-save" class="btn btn-success">Save changes</button>
- </div>
- </div>
- </div>
- </div>`;
- $('body').prepend(modalHtml);
- const $lfsel2 = $('select#langfilter-select2');
- optMap.forEach(function(val, key) {
- $lfsel2.append(
- $('<option>', {
- value: val[0],
- text: key,
- })
- );
- });
- /* Load saved languages */
- let savedLanguage = localStorage.getItem(SAVED_LANGUAGE_KEY);
- let selectedLanguage = [];
- if (savedLanguage) {
- try {
- savedLanguage = JSON.parse(savedLanguage);
- } catch (error) {
- savedLanguage = [];
- console.log(error);
- }
- $.each(savedLanguage, function(_, lang) {
- if (!optMap.has(lang)) return true;
- const val = optMap.get(lang)[0];
- const mim = optMap.get(lang)[1];
- $selectLanguage.append(
- $('<option>', {
- 'value': val,
- 'data-mime': mim,
- 'text': lang,
- 'selected': val == defLang,
- })
- );
- selectedLanguage.push(lang);
- const $opt = $lfsel2.find(`option[value='${val}']`);
- $opt.prop('selected', true);
- moveElementToEndOfParent($opt);
- });
- }
- /* Apply Select2 */
- $lfsel2.select2({
- placeholder: 'Languages',
- theme: 'bootstrap',
- }).on('select2:select', function(evt) {
- const $opt = $(this).children(`option[value=${evt.params.data.id}]`);
- moveElementToEndOfParent($opt);
- $(this).trigger("change");
- });
- const $ul = $('#langfilter-modal > span > span.selection > span > ul.select2-selection__rendered');
- $ul.sortable({
- containment: 'parent',
- update: function() {
- $(this).children("li[title]").each(function(_, li) {
- const $opt = $lfsel2.children('option').filter(function() {
- return $(this).html() == li.title;
- });
- moveElementToEndOfParent($opt);
- });
- }
- });
- $('#langfilter-clear').on('click', function() {
- $lfsel2.val(null).trigger('change');
- });
- $('#langfilter-selectall').on('click', function() {
- $lfsel2.children('option').prop('selected', true);
- $lfsel2.trigger("change");
- });
- $('#langfilter-save').on('click', function() {
- selectedLanguage = [];
- $ul.children('li.select2-selection__choice').each(function() {
- selectedLanguage.push($(this).text().slice(1));
- });
- if (selectedLanguage.length === 0) {
- $('#langfilter-savelabel').removeClass('text-success');
- $('#langfilter-savelabel').addClass('text-danger');
- $('#langfilter-savelabel').text('Please select at least 1 language!');
- } else {
- localStorage.setItem(SAVED_LANGUAGE_KEY, JSON.stringify(selectedLanguage));
- $('#langfilter-savelabel').removeClass('text-danger');
- $('#langfilter-savelabel').addClass('text-success');
- $('#langfilter-savelabel').text(`Saved (${(new Date()).toLocaleString()})`);
- }
- });
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址