ex124OJ

Extend 124OJ!

当前为 2022-12-02 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         ex124OJ
// @namespace    http://tampermonkey.net/
// @version      0.6.0
// @description  Extend 124OJ!
// @author       Sukwants
// @license      MIT
// @match        http://124.221.194.184
// @match        http://124.221.194.184/*
// @icon         https://www.imageoss.com/images/2022/11/29/ex124OJba563861978a769d.png
// @grant        GM_addStyle
// ==/UserScript==


/* ==User Settings== */

// Special Period
const WhenMourn = true;
// Change Page Background. (Image URL, Opacity)
const BackgroundSettings = [];
// Change Site Icon. (Image URL)
const SiteIconImage = 'https://www.imageoss.com/images/2022/11/29/ex124OJba563861978a769d.png';
// Change username color.
const NameColorList = {'Sukwants':['#8e44ad'],'Star32':['#e74c3c'],'2745518585':['#996600'],'syysongyuyang':['#e67e22'],'zsq147258369':['#52c41a'],'zhouchuan':['#e74c3c','#000000']};
// Add CCF level badge.
const CCFBadgeList = {'zsq147258369':'#52c41a'};
// Add name tag badge.
const TagBadgeList = {'Sukwants':['#8e44ad','旅客'],'Star32':['#e74c3c','陌生人'],'2745518585':['#996600','作弊者'],'syysongyuyang':['#e67e22','原批'],'zsq147258369':['#52c41a','boring'],'zhouchuan':['#e74c3c','Feyn']};


const HomepageRegExp = /^http:\/\/124.221.194.184(\/){0,1}(\?.*){0,1}$/;
function isHomepage() {
    return HomepageRegExp.test(window.location.href);
}
const submissionRegExp = /^http:\/\/124.221.194.184\/submission\/\d{1,}/;
function isSubmission() {
    return submissionRegExp.test(window.location.href);
}
const ProblemRegExp = /^http:\/\/124.221.194.184.*\/problem\/(\d{1,})(\?.*){0,1}$/;
function isProblem() {
    return ProblemRegExp.test(window.location.href);
}
const UserProfileRegExp = /^http:\/\/124.221.194.184\/user\/profile\/.{1,}/;
function isUserProfile() {
    return UserProfileRegExp.test(window.location.href);
}
const BlogRegExp = /^http:\/\/124.221.194.184\/blog\/.{1,}/;
function isBlog() {
    return BlogRegExp.test(window.location.href);
}

function whenMourn() {
    if (WhenMourn && isHomepage()) {
        GM_addStyle('\
html {\
-webkit-filter: grayscale(100%);\
-moz-filter: grayscale(100%);\
-ms-filter: grayscale(100%);\
-o-filter: grayscale(100%);\
filter: grayscale(100%);\
filter: gray;\
}');
    }
}

function getBackground() {
    if (BackgroundSettings[0]) return BackgroundSettings[0];
    else return '';
}
function getOpacity() {
    if (BackgroundSettings[1]) return BackgroundSettings[1];
    else return '0.85';
}
function BackgroundImage() {
    if (BackgroundSettings[0]) {
        document.getElementsByClassName('navbar-brand')[0].innerHTML = '<img src="http://124.221.194.184/images/logo_small.png" alt="Logo" class="img-rounded" style="width:39px; height:39px;">';
        document.getElementsByClassName('container')[0].children[0].children[1].innerHTML = document.getElementsByClassName('container')[0].children[0].children[1].innerHTML.match(/(.*> ){0,1}(.*)/)[2];
        GM_addStyle('\
body {\
background: url("' + getBackground() + '");\
background-repeat: no-repeat;\
background-attachment: fixed;\
background-position: 50% 50%;\
background-size: cover;\
}\
.uoj-content {\
background-color: #fff;\
margin: 16px -16px;\
padding: 16px 16px;\
opacity: ' + getOpacity() + ';\
border-radius: 8px;\
}\
.navbar {\
margin: 16px -16px;\
padding: 8px 16px;\
opacity: ' + getOpacity() + ';\
border-radius: 8px;\
}');
    }
}

function getIcon() {
    if (SiteIconImage) return SiteIconImage;
    else return '/images/logo.png';
}
const LogoURLExp = /^.*\/images\/logo(_small){0,1}.png$/;
function changeIcon() {
    var Links = document.getElementsByTagName('link');
    for (var link in Links) {
        if (Links[link] && Links[link].nodeType && Links[link].getAttribute('rel') == 'shortcut icon') {
            Links[link].setAttribute('href', getIcon());
        }
    }
    var Icons = document.getElementsByTagName('img');
    for (var icon in Icons) {
        if (Icons[icon] && Icons[icon].nodeType && LogoURLExp.test(Icons[icon].getAttribute('src'))) {
            Icons[icon].setAttribute('src', getIcon());
        }
    }
}

const ManageStatementExp = /^.*\/manage\/statement(\?.*){0,1}$/
function CodeBlock() {
    GM_addStyle('\
@import url(https://cdn.jsdelivr.net/npm/[email protected]/distr/fira_code.css);\
code {\
    font-family: "Fira Code";\
}\
code.sh_cpp>span {\
    font-style: normal !important;\
    font-weight: 400 !important;\
}\
code.sh_cpp>span.sh_preproc,\
code.sh_cpp>span.sh_keyword,\
code.sh_cpp>span.sh_type {\
    color: #8959a8;\
}\
code.sh_cpp>span.sh_string {\
    color: #718c00;\
}\
code.sh_cpp>span.sh_cbracket {\
    color: #4d4d4c;\
}\
code.sh_cpp>span.sh_symbol {\
    color: #3e999f;\
}\
code.sh_cpp>span.sh_number {\
    color: #f5871f;\
}\
code.sh_cpp>span.sh_function {\
    color: #4271ae;\
}\
code.sh_cpp>span.sh_comment {\
    color: #8e908c;\
}\
.copybutton {\
    float: right;\
    background-color: rgb(0,0,0,.1);\
    padding: .25em .625em;\
    border: 0 solid transparent;\
    border-radius: .28571429rem;\
}\
.copybutton:hover {\
    background-color: rgb(0,0,0,.2);\
}\
.copybutton:focus {\
    background-color: rgb(0,0,0,.2);\
    outline: none;\
}');
    if (!ManageStatementExp.test(window.location.href)) {
        setTimeout(function(){
            var CodeBlocks = document.getElementsByTagName('pre');
            for (var cb in CodeBlocks) {
                if (CodeBlocks[cb] && CodeBlocks[cb].nodeType) {
                    var Content = CodeBlocks[cb].textContent;
                    var InputId = Math.round(Math.random() * 998244353);
                    var ButtonId = Math.round(Math.random() * 998244353);
                    CodeBlocks[cb].innerHTML = '<button class="copybutton" id = "' + ButtonId + '" onclick="\
var ib = document.getElementById(\'' + InputId + '\');\
ib.setAttribute(\'style\', \'display:initial\');\
ib.value = \'' + Content.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/'/g, '\\&#39;').replace(/"/g, '&#34;') + '\';\
ib.select();\
document.execCommand(\'copy\');\
ib.setAttribute(\'style\', \'display:none\');\
var ic = document.getElementById(\'' + ButtonId + '\');\
ic.innerHTML = \'已复制\';\
setTimeout(function() { ic.innerHTML = \'复制\'; }, 500);">复制</button>' + CodeBlocks[cb].innerHTML;
                    var InputBox = document.createElement('textarea');
                    InputBox.setAttribute('id', InputId);
                    InputBox.setAttribute('style', 'display:none');
                    CodeBlocks[cb].appendChild(InputBox);
                }
            }

        }, 30);
    }
}

function NameColor() {
    var Names = document.getElementsByClassName('uoj-username');
    var NeedsRepeat = false;
    for (var i in Names) {
        if (Names[i].innerHTML && NameColorList[Names[i].innerHTML]) {
            Names[i].style = 'color:' + NameColorList[Names[i].innerHTML][0];
            var res = '';
            for (var char = 1; char < NameColorList[Names[i].innerHTML].length; ++char) {
                res = res + '<font style="color:' + NameColorList[Names[i].innerHTML][char] + '">' + Names[i].innerHTML.substring(char - 1, char) + '</font>';
            }
            Names[i].innerHTML = res + Names[i].innerHTML.substring(NameColorList[Names[i].innerHTML].length - 1);
            if (Names[i].parentElement.getAttribute('class') == 'legendLabel') {
                NeedsRepeat = true;
            }
        }
    }
    if (NeedsRepeat) {
        setInterval(function(){
            var Names = document.getElementsByClassName('uoj-username');
            for (var i in Names) {
                if (Names[i].innerHTML && Names[i].parentElement.getAttribute('class') == 'legendLabel' && NameColorList[Names[i].innerHTML]) {
                    Names[i].style = 'color:' + NameColorList[Names[i].innerHTML][0];
                    var res = '';
                    for (var char = 1; char < NameColorList[Names[i].innerHTML].length; ++char) {
                        res = res + '<font style="color:' + NameColorList[Names[i].innerHTML][char] + '">' + Names[i].innerHTML.substring(char - 1, char) + '</font>';
                    }
                    Names[i].innerHTML = res + Names[i].innerHTML.substring(NameColorList[Names[i].innerHTML].length - 1);
                }
            }
        }, 200);
    }
    var Honors = document.getElementsByClassName('uoj-honor');
    for (var j in Honors) {
        if (Honors[j].innerHTML && NameColorList[Honors[j].innerHTML]) {
            Honors[j].style = 'color:' + NameColorList[Honors[j].innerHTML][0];
            var res = '';
            for (var char = 1; char < NameColorList[Honors[j].innerHTML].length; ++char) {
                res = res + '<font style="color:' + NameColorList[Honors[j].innerHTML][char] + '">' + Honors[j].innerHTML.substring(char - 1, char) + '</font>';
            }
            Honors[j].innerHTML = res + Honors[j].innerHTML.substring(NameColorList[Honors[j].innerHTML].length - 1);
        }
    }
}

const NameExp = /^(.{1,}?)( .*){0,1}$/;
function CCFBadge() {
    var Names = document.getElementsByClassName('uoj-username');
    for (var i in Names) {
        if (!Names[i].innerHTML || !NameExp.test(Names[i].textContent)) continue;
        var name = Names[i].textContent.match(NameExp)[1];
        if (CCFBadgeList[name] && Names[i].parentElement.getAttribute('class') != 'legendLabel') {
            Names[i].innerHTML = Names[i].innerHTML + ' <svg width="1em" height="1em" data-v-303bbf52="" aria-hidden="true" focusable="false" data-prefix="fad" data-icon="badge-check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="margin-bottom:.25em!important;bottom:10px;--fa-primary-color:#fff;--fa-secondary-color:' + CCFBadgeList[name] + ';--fa-secondary-opacity:1;"><g data-v-303bbf52="" class="fa-group"><path data-v-303bbf52="" fill="var(--fa-secondary-color)" d="M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z" class="fa-secondary"></path></g></svg>';
        }
    }
    var Honors = document.getElementsByClassName('uoj-honor');
    for (var j in Honors) {
        if (!Honors[j].innerHTML || !NameExp.test(Honors[j].textContent)) continue;
        var honor = Honors[j].textContent.match(NameExp)[1];
        if (CCFBadgeList[honor]) {
            Honors[j].innerHTML = Honors[j].innerHTML + ' <svg width="1em" height="1em" data-v-303bbf52="" aria-hidden="true" focusable="false" data-prefix="fad" data-icon="badge-check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="margin-bottom:.25em!important;bottom:10px;--fa-primary-color:#fff;--fa-secondary-color:' + CCFBadgeList[honor] + ';--fa-secondary-opacity:1;"><g data-v-303bbf52="" class="fa-group"><path data-v-303bbf52="" fill="var(--fa-secondary-color)" d="M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z" class="fa-secondary"></path></g></svg>';
        }
    }
}
function TagBadge() {
    var Names = document.getElementsByClassName('uoj-username');
    for (var i in Names) {
        if (!Names[i].innerHTML || !NameExp.test(Names[i].textContent)) continue;
        var name = Names[i].textContent.match(NameExp)[1];
        if (TagBadgeList[name] && Names[i].parentElement.getAttribute('class') != 'legendLabel') {
            Names[i].innerHTML = Names[i].innerHTML + ' <span style="background-color:' + TagBadgeList[name][0] + ';padding:0.2em 0.6em;border-radius:.2em;color:#fff;font-size:0.7em;font-weight:bold;display:inline-block">' + TagBadgeList[name][1] + '</span>';
        }
    }
    var Honors = document.getElementsByClassName('uoj-honor');
    for (var j in Honors) {
        if (!Honors[j].innerHTML || !NameExp.test(Honors[j].textContent)) continue;
        var honor = Honors[j].textContent.match(NameExp)[1];
        if (TagBadgeList[honor]) {
            Honors[j].innerHTML = Honors[j].innerHTML + ' <span style="background-color:' + TagBadgeList[honor][0] + ';padding:0.2em 0.6em;border-radius:.2em;color:#fff;font-size:0.7em;font-weight:bold;display:inline-block">' + TagBadgeList[honor][1] + '</span>';
        }
    }
}

function TableStyle() {
    var Tables = document.getElementsByTagName('table');
    for (var table in Tables) {
        if (Tables[table].nodeType && Tables[table].parentNode.getAttribute('class') != 'legend' && !Tables[table].classList.length) {
            Tables[table].classList.add('table', 'table-bordered');
        }
    }
    var ths = document.getElementsByTagName('th');
    for (var th in ths) {
        if (ths[th].nodeType && ths[th].getAttribute('align')) {
            ths[th].setAttribute('style', 'text-align:' + ths[th].getAttribute('align'));
        }
    }
}

function SubmissionCard() {
    setTimeout(function() {
        var Content = document.getElementsByClassName('uoj-content')[0];
        if (Content.childElementCount == 3) {
            var Table = Content.children[0];
            var TabList = document.createElement('ul');
            TabList.setAttribute('class', 'nav nav-tabs');
            TabList.setAttribute('role', 'tablist');
            TabList.innerHTML = '<li class="nav-item"><a class="nav-link active" href="#test-cases" role="tab" data-toggle="tab" aria-selected="true"><span class="glyphicon glyphicon-check"></span> 测试点信息</a></li><li class="nav-item"><a class="nav-link" href="#source" role="tab" data-toggle="tab" aria-selected="false"><span class="glyphicon glyphicon-file"></span> 源代码</a></li>';
            var TabContent = document.createElement('div');
            TabContent.setAttribute('class', 'tab-content');
            TabContent.innerHTML = '<div class="tab-pane card active" id="test-cases"><div class="card-body">' + Content.children[2].children[1].innerHTML + '</div></div><div class="tab-pane card" id="source"><div class="card-body">' + Content.children[1].children[1].innerHTML + '</div></div>';
            Content.innerHTML = "";
            Content.appendChild(Table);
            Content.appendChild(TabList);
            Content.appendChild(TabContent);
        }
    }, 50);
}

function downloadData() {
    var DownloadTag = document.createElement('a');
    DownloadTag.setAttribute('role', 'button');
    DownloadTag.setAttribute('class', 'btn btn-primary float-right');
    DownloadTag.setAttribute('href', '/download.php?type=problem&id=' + window.location.href.match(ProblemRegExp)[1]);
    DownloadTag.setAttribute('target', '_blank');
    DownloadTag.innerHTML = '<span class="glyphicon glyphicon-download-alt"></span> 下载数据';
    document.getElementsByClassName("btn btn-info float-right")[0].after(DownloadTag);
}

const GravatarURLRegExp = /\/\/cn.gravatar.com\/avatar\/(.*)$/;
function changeGravatarURL() {
    var Gravatar = document.getElementsByClassName('img-thumbnail')[0];
    if (Gravatar && Gravatar.nodeType){
        console.log(Gravatar);
        Gravatar.setAttribute('src', '//gravatar.loli.net/avatar/' + Gravatar.getAttribute('src').match(GravatarURLRegExp)[1]);
    }
    var Gravatars = document.getElementsByClassName('img-rounded');
    for (var gravatar in Gravatars) {
        if (Gravatars[gravatar] && Gravatars[gravatar].nodeType && GravatarURLRegExp.test(Gravatars[gravatar].getAttribute('src'))) {
            Gravatars[gravatar].setAttribute('src', '//gravatar.loli.net/avatar/' + Gravatars[gravatar].getAttribute('src').match(GravatarURLRegExp)[1]);
        }
    }
}

(function() {
    'use strict';
    whenMourn();
    BackgroundImage();
    changeIcon();
    CodeBlock();
    NameColor();
    CCFBadge();
    TagBadge();
    TableStyle();
    if (isSubmission()) SubmissionCard();
    if (isProblem()) downloadData();
    if (isUserProfile() || isBlog()) changeGravatarURL();
})();