您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Displays Twitter IDs in contest standings.
// ==UserScript== // @name AtCoder Contest Standings with Twitter ID // @namespace https://twitter.com/KakurenboUni // @version 1.0.4 // @match https://atcoder.jp/contests/*/standings* // @description Displays Twitter IDs in contest standings. // @author uni-kakurenbo // @license MIT // @supportURL https://twitter.com/KakurenboUni // ==/UserScript== void function() { "use strict"; // ac-predictor などと併用すると,列の一部が見切れてしまうことがあります. // その場合は以下の行をコメントアウトし,順位表の幅を広げてください.(サイズは任意に変更していただいて構いません.) // document.querySelector("#main-container").style.width = "1380px" const cache = new Map(); const STORAGE_ID_PREFIX = "AtCoder-Contest-Standings-with-Twitter-ID" window.onload = async function() { await rendered(); const $checkboxes = Array.from(document.querySelectorAll("div.checkbox")); const $outerDivElement = document.createElement("div"); $outerDivElement.innerHTML = `<label><input id="checkbox-twitter" type="checkbox"> Twitter ID を表示</label>`; $outerDivElement.className = "checkbox"; $checkboxes[2].after($outerDivElement); const $addedCheckbox = document.querySelector("input#checkbox-twitter"); $addedCheckbox.checked = localStorage.getItem(`${STORAGE_ID_PREFIX}.enable`) === "true"; setVisuality(); if(isAvailable() && $addedCheckbox.checked) display(); $addedCheckbox.addEventListener('click', ({ target : { checked } }) => { if(checked) display(); else hide(); }); $checkboxes.at(-1).addEventListener("click", setVisuality); document.querySelectorAll(".standings-per-page").forEach(element => { element.addEventListener("click", setVisuality); }) function isAvailable() { return +document.querySelector("a.standings-per-page.selected").textContent <= 50 || $checkboxes.at(-1).querySelector("input").checked } function setVisuality() { if(isAvailable()) $addedCheckbox.disabled = false; else { $addedCheckbox.checked = false; $addedCheckbox.disabled = true; } } }; function display() { const $usernames = document.querySelectorAll(".standings-rank + .standings-username .username") $usernames.forEach(async ($username) => { const username = $username.textContent; const existing = cache.get(username); let twitterId = ""; if(existing) { twitterId = existing; } else { const response = await fetch($username.href); const row_text = await response.text(); const twitterInfomation = row_text.match(/href='\/\/twitter.com\/(.*)'/); if(!twitterInfomation) return; twitterId = twitterInfomation[1]; cache.set(username, twitterId) } const $span = document.createElement("span"); $span.className = "twitter-link"; $span.style["margin-left"] = "5px" $span.style["margin-right"] = "2px" $span.innerHTML = `<a href="https://twitter.com/@${twitterId}" target="_blank" rel="noopener noreferrer">@${twitterId}</a>` $username.after($span); }) localStorage.setItem(`${STORAGE_ID_PREFIX}.enable`, true); } function hide() { const $targets = document.querySelectorAll(".twitter-link") $targets.forEach($target => $target.remove()); localStorage.setItem(`${STORAGE_ID_PREFIX}.enable`, false); } async function rendered() { let timer; await new Promise((resolve) => { observer(); function observer() { if(document.querySelector("div.checkbox")) { resolve(); } timer = setTimeout(observer, 10); }; }); clearTimeout(timer) } }();