-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLuogu-Helper.user.js
156 lines (138 loc) · 5.38 KB
/
Luogu-Helper.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// ==UserScript==
// @name Luogu Helper
// @name:zh-CN 洛谷助手
// @description Print elegantly | Show difficulty
// @description:zh-CN 优雅打印 | 显示难度
// @namespace work.pythoner
// @match *://*.luogu.com.cn/*
// @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
// @run-at document-end
// @grant GM_registerMenuCommand
// @grant GM_xmlhttpRequest
// @grant GM_listValues
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_log
// @version 1.0
// @author Hanson Hu
// @homepage https://blog.pythoner.work
// @icon https://blog.pythoner.work/favicon.ico
// @license MIT
// ==/UserScript==
$.noConflict();
jQuery(document).ready(function() {
function getToday() {
// local tz
let ret = new Date().toLocaleString('sv').slice(0, 10);
return ret;
}
function getTail(str) {
let index = str.lastIndexOf('\/');
return str.substring(index + 1, str.length);
}
function getCache(key) {
const value = GM_getValue(key);
if (value === undefined) return false;
const obj = JSON.parse(value);
const curr = Date.now();
if (curr - obj.time > CACHE_LIFESPAN) {
GM_deleteValue(key);
GM_log('Deleted key ' + key);
return false;
} else {
return obj.data;
}
}
function setCache(key, value) {
const curr = Date.now();
GM_setValue(key, JSON.stringify({data: value, time: curr}));
GM_log('Added key ' + key);
}
function getCFDifficulty() {
let ret = getCache(pnum);
if (ret) return ret;
const re = /CF(\d+)(\w+)/;
let t1 = re.exec(pnum)[1],
t2 = re.exec(pnum)[2];
GM_xmlhttpRequest({
method: 'GET',
url: 'https://codeforces.com/problemset/problem/' +
t1 + '/' + t2,
// synchronous is not supported
synchronous: true,
timeout: 10000,
onload: function(response) {
const re = /<span.+? title="Difficulty">\s*([*0-9]+)\s*<\/span>/,
html = response.responseText;
ret = re.exec(html)[1];
setCache(pnum, ret);
},
onerror: function(e) {
console.error('Access CodeForces error ', e);
},
ontimeout: function(e) {
console.error('Access CodeForces timeout ', e);
}
});
return ret;
}
function showDifficulty() {
let cfd = getCFDifficulty();
if (cfd && !flag) {
difficulty = cfd + '/' + difficulty;
flag = true;
jQuery('.side a[href^="/problem/list?difficulty="] span').text(difficulty);
}
}
function getDeferredValue() {
pnum = getTail(window.location.href);
title = jQuery('.header h1 span').prop('title').replace(pnum, '').trim();
problem = jQuery('.main .problem-card div').eq(1).html().trim();
difficulty = jQuery('.side a[href^="/problem/list?difficulty="] span').text().trim();
if (pnum.startsWith('CF')) showDifficulty();
}
function onClickPrint() {
jQuery('#app').remove();
let elem = '<h1 class="lfe-h1"><span title="' + title +
'">LG' + pnum + '. ' + title +
'</span></h1>';
jQuery('body').append(elem);
elem = '<div><p>' + difficulty + '</p></div>';
jQuery('body').append(elem);
elem = problem.replaceAll(/\sdata-v-\w+=""/g, '');
jQuery('body').append(elem);
elem = '<div style="position: absolute; top: 2px; right: 2px; ' +
'font-family: Bahnschrift, Trebuchet MS, sans-serif; ' +
'font-weight: lighter; font-stretch: condensed; ' +
'font-size: 20px;">' + getToday() + '</div>';
jQuery('body').append(elem);
jQuery('.lfe-h1').css({'font-size': '1.5em', 'font-weight': 'normal'});
jQuery('.lfe-h2').css('margin-bottom', '0');
jQuery('.lfe-h3').css('margin-bottom', '0');
jQuery('.sample .input').css({'border': '1px solid #eee', 'margin': '0.25em 0', 'padding': '0.25em'});
jQuery('.sample .output').css({'border': '1px solid #eee', 'margin': '0.25em 0', 'padding': '0.25em'});
jQuery('.sample .copy-btn').css('display', 'none');
jQuery('body').css({'zoom': '80%', 'padding': '2em 3em 2em 3em', 'font-size': '14px'});
}
function onClickPurgeCache() {
const curr = Date().now();
let arr = new Array();
for (const key of GM_listValues()) {
const obj = JSON.parse(GM_getValue(key));
if (curr - obj.time > CACHE_LIFESPAN) arr.push(key);
}
for (const key of arr) {
GM_deleteValue(key);
GM_log('Deleted key ' + key);
}
}
GM_registerMenuCommand('Prepare to print', onClickPrint);
GM_registerMenuCommand('Purge cache', onClickPurgeCache);
const CACHE_LIFESPAN = 30 * 86400 * 1000;
let pnum, title, problem, difficulty, flag = false;
// Luogu load content lazily
setTimeout(getDeferredValue, 1000);
// update asynchronous result
setTimeout(showDifficulty, 4000);
});