ex124OJ

Extend 124OJ!

目前为 2022-11-30 提交的版本。查看 最新版本

// ==UserScript==
// @name         ex124OJ
// @namespace    http://tampermonkey.net/
// @version      0.5.8
// @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== */

// 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':'#b0e0e6'};
// 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':['#b0e0e6','Feyn']};


function whenMourn() {
    GM_addStyle('\
html {\
-webkit-filter: grayscale(100%);\
-moz-filter: grayscale(100%);\
-ms-filter: grayscale(100%);\
-o-filter: grayscale(100%);\
filter: grayscale(100%);\
filter: gray;\
}');
    var Banner = document.createElement('img');
    Banner.setAttribute('src', 'https://www.imageoss.com/images/2022/11/30/cb6a1d050e324a8b6ec7996b0a398f7376e9e2bd.png3840w_360h_1c_90q74cf9fde037f143b.jpg');
    Banner.setAttribute('style', 'width:100%; margin: -50px 0');
    document.getElementsByTagName('body')[0].children[0].children[0].before(Banner);
    document.getElementsByTagName('body')[0].children[0].children[1].children[1].setAttribute('style', 'color:white');
}

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];
            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];
                }
            }
        }, 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];
        }
    }
}

const NameWithBadge = /^(.{1,}?)( <.*){0,1}$/;
function CCFBadge() {
    var Names = document.getElementsByClassName('uoj-username');
    for (var i in Names) {
        if (!Names[i].innerHTML || !NameWithBadge.test(Names[i].innerHTML)) continue;
        var name = Names[i].innerHTML.match(NameWithBadge)[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 || !NameWithBadge.test(Honors[j].innerHTML)) continue;
        var honor = Honors[j].innerHTML.match(NameWithBadge)[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 || !NameWithBadge.test(Names[i].innerHTML)) continue;
        var name = Names[i].innerHTML.match(NameWithBadge)[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 || !NameWithBadge.test(Honors[j].innerHTML)) continue;
        var honor = Honors[j].innerHTML.match(NameWithBadge)[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'));
        }
    }
}

const submissionRegExp = /^http:\/\/124.221.194.184\/submission\/\d{1,}/;
function isSubmission() {
    return submissionRegExp.test(window.location.href);
}
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);
}

const ProblemRegExp = /^http:\/\/124.221.194.184.*\/problem\/(\d{1,})(\?.*){0,1}$/;
function isProblem() {
    return ProblemRegExp.test(window.location.href);
}
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 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);
}
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();
})();