To better display Leetcode ProblemSet Stat; to hide and dismiss the locked problems.
当前为
// ==UserScript==
// @name Leetcode ProblemSet Stat Better Display
// @namespace
// @description To better display Leetcode ProblemSet Stat; to hide and dismiss the locked problems.
// @version 0.1
// @author pcm
// @match https://leetcode.com/problemset/*
// @match https://leetcode.com/tag/*
// @run-at document-start
// @grant GM_xmlhttpRequest
// @connect leetcode.com
// ==/UserScript==
// some global configuration
CONF = {
'SVG_HEIGHT': 480,
'SVG_WIDTH': 300,
'COLOR_AC': '#7bc96f',
'COLOR_TODO': '#ebedf0',
'CELL_HEIGHT': 10,
'CELL_WIDTH': 10,
'CELL_MARGIN': 2,
'CELL_W_COUNT': 25,
}
// if switchHideLockedProblems == true, hide all locked problems in problemset
function statDifficulty(problemTable, switchHideLockedProblems, switchDrawProgressBar) {
var res = {
'num_total_easy': 0,
'num_total_normal': 0,
'num_total_hard': 0,
'num_total': 0,
'num_ac_easy': 0,
'num_ac_normal': 0,
'num_ac_hard': 0,
'num_ac': 0,
}
// find all related indices
var index = {}
var thead = problemTable.getElementsByTagName('thead')[0];
var ths = thead.getElementsByTagName("th");
for (var i = 0; i < ths.length; i++) {
var th = ths[i];
if (th.textContent == 'Difficulty') index['difficulty'] = i;
if (th.textContent == '\xa0') index['status'] = i;
if (th.textContent == 'Title') index['title'] = i;
if (th.textContent == '#') index['#'] = i;
}
if (keys(index).indexOf('status') == -1) index['status'] = 0;
if (keys(index).indexOf('#') == -1) index['#'] = 1;
var tbody = problemTable.getElementsByTagName('tbody')[0];
var trs = tbody.getElementsByTagName("tr");
for ( var i = 0; i < trs.length; i++) {
var tds = trs[i].getElementsByTagName("td");
var td_status = tds[index['status']];
var td_title = tds[index['title']];
var td_difficulty = tds[index['difficulty']];
var td_number = tds[index['#']];
// dismiss locked problems
var locked = td_title.getElementsByClassName('fa-lock');
if (locked[0]) {
if (switchHideLockedProblems) {
trs[i].innerHTML = "";
}
continue;
}
// stat difficulty
var hard = td_difficulty.getElementsByClassName('label-danger');
var normal = td_difficulty.getElementsByClassName('label-warning');
var easy = td_difficulty.getElementsByClassName('label-success');
var ac = td_status.getElementsByClassName('fa-check');
if (switchDrawProgressBar) {
var title = td_number.textContent + ' ' + td_title.firstChild.firstChild.textContent;
drawOneCell(res['num_total'], ac[0] ? true : false, title);
}
if (hard[0]) {
res['num_total_hard']++;
if (ac[0]) res['num_ac_hard']++;
}
else if (normal[0]) {
res['num_total_normal']++;
if (ac[0]) res['num_ac_normal']++;
}
else if (easy[0]) {
res['num_total_easy']++;
if (ac[0]) res['num_ac_easy']++;
}
res['num_total']++;
if (ac[0]) res['num_ac']++;
}
return res;
}
function updateStatBar(welcomes) {
var statBar = document.getElementById('welcome');
if (!statBar) {
var div = document.getElementsByClassName('header__2ZIe')[0];
var p = div.getElementsByTagName('p')[1];
p.innerHTML = '<div id="welcome"><span><span class="label label-primary round">Solved</span> - <span class="label label-success round"></span> <span class="label label-warning round"></span> <span class="label label-danger round"></span></span></div>';
statBar = document.getElementById('welcome');
}
var total = statBar.getElementsByClassName('label-primary')[0];
var hard = statBar.getElementsByClassName('label-danger')[0];
var normal = statBar.getElementsByClassName('label-warning')[0];
var easy = statBar.getElementsByClassName('label-success')[0];
total.textContent = welcomes['num_ac'].toString() + '/' + welcomes['num_total'].toString() + ' Solved';
hard.textContent = 'Hard ' + welcomes['num_ac_hard'].toString() + '/' + welcomes['num_total_hard'].toString();
normal.textContent = 'Medium ' + welcomes['num_ac_normal'].toString() + '/' + welcomes['num_total_normal'].toString();
easy.textContent = 'Easy ' + welcomes['num_ac_easy'].toString() + '/' + welcomes['num_total_easy'].toString();
}
function drawOneCell(i, ac, title) {
var svg = document.getElementById('gm_progress_graph');
var x = (i % CONF['CELL_W_COUNT']) * (CONF['CELL_MARGIN'] + CONF['CELL_WIDTH']);
var y = Math.floor(i / CONF['CELL_W_COUNT']) * (CONF['CELL_MARGIN'] + CONF['CELL_HEIGHT']);
var rectHTML =
'<rect ' +
'width="' + CONF['CELL_WIDTH'] + '" ' +
'height="' + CONF['CELL_HEIGHT'] + '" ' +
'x="' + x.toString() + '" ' +
'y="' + y.toString() + '" ' +
'fill="' + (ac ? CONF['COLOR_AC'] : CONF['COLOR_TODO']) + '" ';
if (ac) {
rectHTML += '>' +
'<title>' + title + '</title>' +
'</rect>'
}
else {
rectHTML += '/>';
}
svg.insertAdjacentHTML('beforeend', rectHTML);
svg.setAttribute('height', y + (CONF['CELL_MARGIN'] + CONF['CELL_HEIGHT']));
}
function initDrawProgressGraph() {
var div = document.getElementsByClassName('progress-panel-base');
if (!div[0]) div = document.getElementsByClassName('header__2ZIe')[0];
else div = div[0].firstChild;
var svgHTML =
'<div><svg ' +
'width="' + CONF['SVG_WIDTH'] + '" ' +
'height="' + CONF['SVG_HEIGHT'] + '" ' +
'id="gm_progress_graph" xmlns="http://www.w3.org/2000/svg"' +
'>' +
'<rect width="100%" height="100%" style="fill:white;/> ' +
'</svg></div>'
div.insertAdjacentHTML('afterend', svgHTML);
return true;
}
function changeStatInfo() {
var problemTable = document.getElementsByClassName('question-list-table');
if (!problemTable[0])
problemTable = document.getElementsByClassName('table__XKyc');
if (problemTable[0]) {
var switchHideLockedProblems = true;
var switchDrawProgressBar = initDrawProgressGraph();
var welcomes = statDifficulty(problemTable[0], switchHideLockedProblems, switchDrawProgressBar);
updateStatBar(welcomes);
}
}
changeStatInfo()
window.addEventListener("DOMContentLoaded", function load() {
window.removeEventListener("DOMContentLoaded", load, false);
// For initial page load
changeStatInfo();
}, false);