//
// qianjunakasumi <qianjunakasumi@outlook.com>
// [qianjunakasumi] 千橘雫霞(https://github.com/qianjunakasumi)
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// ==UserScript==
// @name 智学网排行榜
// @namespace ren.qianjunakasumi
// @version 1.0.2
// @author qianjunakasumi
// @description 智学网排名计算
// @source https://github.com/qianjunakasumi/ZhiXueRank
// @updateURL https://github.com/qianjunakasumi/ZhiXueRank/blob/main/main.js
// @downloadURL https://github.com/qianjunakasumi/ZhiXueRank/blob/main/main.js
// @supportURL https://github.com/qianjunakasumi/ZhiXueRank/issues/new/choose
// @match https://www.zhixue.com/activitystudy/web-report/index.html?from=web-container_top
// @grant none
// ==/UserScript==
const GLOBALDATA = {
data: {},
newCode: id => {
if (!!GLOBALDATA.data[id]) {
return;
}
GLOBALDATA.data[id] = {
number: 0,
subject: {},
};
},
addNumber: (id, n) => {
GLOBALDATA.newCode(id);
GLOBALDATA.data[id].number = n;
},
addRank: (id, n, o) => {
GLOBALDATA.newCode(id);
GLOBALDATA.data[id].subject[n] = {
rank: -1,
org: o,
};
},
calc: id => {
const e = GLOBALDATA.data[id];
const keys = Object.keys(e.subject);
if (e.number === 0 || keys.length === 0) {
return;
}
for (const ki in keys) {
const k = keys[ki];
if (e.subject[k].rank !== -1) {
return;
}
GLOBALDATA.data[id].subject[k].rank = Math.trunc(e.number * e.subject[k].org / 100) + 1;
}
display(id);
},
};
function display(id) {
let html = `
<div>
<div class="general" style="padding-bottom: 0">
<div class="general-head specific">
<h2 class="class-a-title">班级排行榜</h2>
<div style="margin-bottom: 12px"></div>
考试人数 ${GLOBALDATA.data[id].number}
</div>
</div>
<div class="single">`;
const keys = Object.keys(GLOBALDATA.data[id].subject);
for (const ki in keys) {
const k = keys[ki];
html += `<div style="display: inline-block; width: 50%; margin-bottom: 15px;"><div class="subject">${k}</div><div style="margin-left: 120px;"><div class="bottom"><div><span class="blue">${GLOBALDATA.data[id].subject[k].rank}</span><span class="specific"> 名</span></div></div></div></div>`;
}
html += `
</div>
</div>
`;
let rankDOM = document.createElement('div');
rankDOM.classList.add('hierarchy');
rankDOM.id = 'qianjuzhixuerank';
rankDOM.innerHTML = html;
document.querySelector('#report > div > div.report > div > div').insertBefore(rankDOM, document.querySelector('#report > div > div.report > div > div > div:nth-child(2)'));
}
function patchRequest(url, xhr) {
if (url.indexOf('https://www.zhixue.com/zhixuebao/report/exam/getSubjectDiagnosis') !== -1) {
xhr.addEventListener("load", patchGetSubjectDiagnosisOnReadyStateChange);
}
if (url.indexOf('https://www.zhixue.com/zhixuebao/report/exam/getLevelTrend') !== -1) {
xhr.addEventListener("load", patchGetLevelTrendOnReadyStateChange);
}
}
function patchGetSubjectDiagnosisOnReadyStateChange(proto) {
const xhr = proto.currentTarget;
if (xhr.readyState !== 4) {
return;
}
const code = xhr.responseURL.substring(72, 108);
const data = JSON.parse(xhr.response);
data.result.list.forEach(element => {
GLOBALDATA.addRank(code, element.subjectName, element.rationalRank);
});
GLOBALDATA.calc(code);
}
function patchGetLevelTrendOnReadyStateChange(proto) {
const xhr = proto.currentTarget;
if (xhr.readyState !== 4) {
return;
}
const code = xhr.responseURL.substring(66, 102);
const data = JSON.parse(xhr.response);
GLOBALDATA.addNumber(code, data.result.list[0].statTotalNum);
GLOBALDATA.calc(code);
}
// https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/open
function inject() {
XMLHttpRequest.prototype._open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
patchRequest(url, this);
this._open(method, url, async, user, password);
};
}
(function () {
'use strict';
inject();
})();