xmoj-script 2.1.1 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Update.json +22 -0
- package/XMOJ.user.js +89 -15
- package/package.json +1 -1
package/Update.json
CHANGED
@@ -2980,6 +2980,28 @@
|
|
2980
2980
|
}
|
2981
2981
|
],
|
2982
2982
|
"Notes": "No release notes were provided for this release."
|
2983
|
+
},
|
2984
|
+
"2.1.2": {
|
2985
|
+
"UpdateDate": 1755589063111,
|
2986
|
+
"Prerelease": true,
|
2987
|
+
"UpdateContents": [
|
2988
|
+
{
|
2989
|
+
"PR": 834,
|
2990
|
+
"Description": "feat: use credential management api"
|
2991
|
+
}
|
2992
|
+
],
|
2993
|
+
"Notes": "No release notes were provided for this release."
|
2994
|
+
},
|
2995
|
+
"2.1.3": {
|
2996
|
+
"UpdateDate": 1755596470421,
|
2997
|
+
"Prerelease": true,
|
2998
|
+
"UpdateContents": [
|
2999
|
+
{
|
3000
|
+
"PR": 835,
|
3001
|
+
"Description": "feat: add user-selectable theme"
|
3002
|
+
}
|
3003
|
+
],
|
3004
|
+
"Notes": "No release notes were provided for this release."
|
2983
3005
|
}
|
2984
3006
|
}
|
2985
3007
|
}
|
package/XMOJ.user.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
// ==UserScript==
|
2
2
|
// @name XMOJ
|
3
|
-
// @version 2.1.
|
3
|
+
// @version 2.1.3
|
4
4
|
// @description XMOJ增强脚本
|
5
5
|
// @author @XMOJ-Script-dev, @langningchen and the community
|
6
6
|
// @namespace https://github/langningchen
|
@@ -441,6 +441,35 @@ let UtilityEnabled = (Name) => {
|
|
441
441
|
}
|
442
442
|
}
|
443
443
|
};
|
444
|
+
let storeCredential = async (username, password) => {
|
445
|
+
if ('credentials' in navigator && window.PasswordCredential) {
|
446
|
+
try {
|
447
|
+
const credential = new PasswordCredential({ id: username, password: password });
|
448
|
+
await navigator.credentials.store(credential);
|
449
|
+
} catch (e) {
|
450
|
+
console.error(e);
|
451
|
+
}
|
452
|
+
}
|
453
|
+
};
|
454
|
+
let getCredential = async () => {
|
455
|
+
if ('credentials' in navigator && window.PasswordCredential) {
|
456
|
+
try {
|
457
|
+
return await navigator.credentials.get({ password: true, mediation: 'optional' });
|
458
|
+
} catch (e) {
|
459
|
+
console.error(e);
|
460
|
+
}
|
461
|
+
}
|
462
|
+
return null;
|
463
|
+
};
|
464
|
+
let clearCredential = async () => {
|
465
|
+
if ('credentials' in navigator && window.PasswordCredential) {
|
466
|
+
try {
|
467
|
+
await navigator.credentials.preventSilentAccess();
|
468
|
+
} catch (e) {
|
469
|
+
console.error(e);
|
470
|
+
}
|
471
|
+
}
|
472
|
+
};
|
444
473
|
let RequestAPI = (Action, Data, CallBack) => {
|
445
474
|
try {
|
446
475
|
let Session = "";
|
@@ -523,6 +552,24 @@ let CurrentUsername = document.querySelector("#profile").innerText;
|
|
523
552
|
CurrentUsername = CurrentUsername.replaceAll(/[^a-zA-Z0-9]/g, "");
|
524
553
|
let IsAdmin = AdminUserList.indexOf(CurrentUsername) !== -1;
|
525
554
|
|
555
|
+
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
|
556
|
+
const applyTheme = (theme) => {
|
557
|
+
document.querySelector("html").setAttribute("data-bs-theme", theme);
|
558
|
+
localStorage.setItem("UserScript-Setting-DarkMode", theme === "dark" ? "true" : "false");
|
559
|
+
};
|
560
|
+
const applySystemTheme = (e) => applyTheme(e.matches ? "dark" : "light");
|
561
|
+
let initTheme = () => {
|
562
|
+
const saved = localStorage.getItem("UserScript-Setting-Theme") || "auto";
|
563
|
+
if (saved === "auto") {
|
564
|
+
applyTheme(prefersDark.matches ? "dark" : "light");
|
565
|
+
prefersDark.addEventListener("change", applySystemTheme);
|
566
|
+
} else {
|
567
|
+
applyTheme(saved);
|
568
|
+
prefersDark.removeEventListener("change", applySystemTheme);
|
569
|
+
}
|
570
|
+
};
|
571
|
+
initTheme();
|
572
|
+
|
526
573
|
|
527
574
|
class NavbarStyler {
|
528
575
|
constructor() {
|
@@ -962,8 +1009,7 @@ async function main() {
|
|
962
1009
|
location.href = "https://www.xmoj.tech/modifypage.php?ByUserScript=1";
|
963
1010
|
});
|
964
1011
|
PopupUL.children[5].addEventListener("click", () => {
|
965
|
-
|
966
|
-
localStorage.removeItem("UserScript-Password");
|
1012
|
+
clearCredential();
|
967
1013
|
document.cookie = "PHPSESSID=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/"; //This is how you remove a cookie?
|
968
1014
|
location.href = "https://www.xmoj.tech/logout.php";
|
969
1015
|
});
|
@@ -1331,7 +1377,32 @@ async function main() {
|
|
1331
1377
|
} else if (Data[i].Type == "D") {
|
1332
1378
|
Row.classList.add("list-group-item-danger");
|
1333
1379
|
}
|
1334
|
-
if (Data[i].
|
1380
|
+
if (Data[i].ID == "Theme") {
|
1381
|
+
let Label = document.createElement("label");
|
1382
|
+
Label.classList.add("me-2");
|
1383
|
+
Label.htmlFor = "UserScript-Setting-Theme";
|
1384
|
+
Label.innerText = Data[i].Name;
|
1385
|
+
Row.appendChild(Label);
|
1386
|
+
let Select = document.createElement("select");
|
1387
|
+
Select.classList.add("form-select", "form-select-sm", "w-auto", "d-inline");
|
1388
|
+
Select.id = "UserScript-Setting-Theme";
|
1389
|
+
[
|
1390
|
+
["light", "亮色"],
|
1391
|
+
["dark", "暗色"],
|
1392
|
+
["auto", "跟随系统"]
|
1393
|
+
].forEach(opt => {
|
1394
|
+
let option = document.createElement("option");
|
1395
|
+
option.value = opt[0];
|
1396
|
+
option.innerText = opt[1];
|
1397
|
+
Select.appendChild(option);
|
1398
|
+
});
|
1399
|
+
Select.value = localStorage.getItem("UserScript-Setting-Theme") || "auto";
|
1400
|
+
Select.addEventListener("change", () => {
|
1401
|
+
localStorage.setItem("UserScript-Setting-Theme", Select.value);
|
1402
|
+
initTheme();
|
1403
|
+
});
|
1404
|
+
Row.appendChild(Select);
|
1405
|
+
} else if (Data[i].Children == undefined) {
|
1335
1406
|
let CheckBox = document.createElement("input");
|
1336
1407
|
CheckBox.classList.add("form-check-input");
|
1337
1408
|
CheckBox.classList.add("me-1");
|
@@ -1389,7 +1460,7 @@ async function main() {
|
|
1389
1460
|
}, {"ID": "ResetType", "Type": "F", "Name": "重新排版*"}, {
|
1390
1461
|
"ID": "AddColorText", "Type": "A", "Name": "增加彩色文字"
|
1391
1462
|
}, {"ID": "AddUnits", "Type": "A", "Name": "状态界面内存与耗时添加单位"}, {
|
1392
|
-
"ID": "
|
1463
|
+
"ID": "Theme", "Type": "A", "Name": "界面主题"
|
1393
1464
|
}, {"ID": "AddAnimation", "Type": "A", "Name": "增加动画"}, {
|
1394
1465
|
"ID": "ReplaceYN", "Type": "F", "Name": "题目前状态提示替换为好看的图标"
|
1395
1466
|
}, {"ID": "RemoveAlerts", "Type": "D", "Name": "去除多余反复的提示"}, {
|
@@ -3213,12 +3284,11 @@ async function main() {
|
|
3213
3284
|
.then((Response) => {
|
3214
3285
|
return Response.text();
|
3215
3286
|
})
|
3216
|
-
.then((Response) => {
|
3287
|
+
.then(async (Response) => {
|
3217
3288
|
if (UtilityEnabled("LoginFailed")) {
|
3218
3289
|
if (Response.indexOf("history.go(-2);") != -1) {
|
3219
3290
|
if (UtilityEnabled("SavePassword")) {
|
3220
|
-
|
3221
|
-
localStorage.setItem("UserScript-Password", Password);
|
3291
|
+
await storeCredential(Username, Password);
|
3222
3292
|
}
|
3223
3293
|
let NewPage = localStorage.getItem("UserScript-LastPage");
|
3224
3294
|
if (NewPage == null) {
|
@@ -3227,8 +3297,7 @@ async function main() {
|
|
3227
3297
|
location.href = NewPage;
|
3228
3298
|
} else {
|
3229
3299
|
if (UtilityEnabled("SavePassword")) {
|
3230
|
-
|
3231
|
-
localStorage.removeItem("UserScript-Password");
|
3300
|
+
clearCredential();
|
3232
3301
|
}
|
3233
3302
|
Response = Response.substring(Response.indexOf("alert('") + 7);
|
3234
3303
|
Response = Response.substring(0, Response.indexOf("');"));
|
@@ -3244,10 +3313,15 @@ async function main() {
|
|
3244
3313
|
});
|
3245
3314
|
}
|
3246
3315
|
});
|
3247
|
-
if (UtilityEnabled("SavePassword")
|
3248
|
-
|
3249
|
-
|
3250
|
-
|
3316
|
+
if (UtilityEnabled("SavePassword")) {
|
3317
|
+
(async () => {
|
3318
|
+
let Credential = await getCredential();
|
3319
|
+
if (Credential) {
|
3320
|
+
document.querySelector("#login > div:nth-child(1) > div > input").value = Credential.id;
|
3321
|
+
document.querySelector("#login > div:nth-child(2) > div > input").value = Credential.password;
|
3322
|
+
LoginButton.click();
|
3323
|
+
}
|
3324
|
+
})();
|
3251
3325
|
}
|
3252
3326
|
} else if (location.pathname == "/contest_video.php" || location.pathname == "/problem_video.php") {
|
3253
3327
|
let ScriptData = document.querySelector("body > div > div.mt-3 > center > script").innerHTML;
|
@@ -3814,7 +3888,7 @@ int main()
|
|
3814
3888
|
AddUser.disabled = true;
|
3815
3889
|
RequestAPI("SendMail", {
|
3816
3890
|
"ToUser": String(UsernameData),
|
3817
|
-
"Content": String("您好,我是" +
|
3891
|
+
"Content": String("您好,我是" + CurrentUsername)
|
3818
3892
|
}, (ResponseData) => {
|
3819
3893
|
AddUser.children[0].style.display = "none";
|
3820
3894
|
AddUser.disabled = false;
|