更好用的NXU

让NXU更好用!

  1. // ==UserScript==
  2. // @name 更好用的NXU
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.7.1
  5. // @description 让NXU更好用!
  6. // @author H
  7. // @license Apache Licence
  8. // @match https://webvpn.nxu.edu.cn/*
  9. // @match https://jwgl.nxu.edu.cn/*
  10. // @grant unsafeWindow
  11. // @grant GM_addStyle
  12. // @grant GM_xmlhttpRequest
  13. // @grant GM_setValue
  14. // @grant GM_getValue
  15. // @grant GM_deleteValue
  16. // @grant GM_listValues
  17. // @grant GM_getResourceText
  18. // @grant GM_getResourceURL
  19. // @grant window.close
  20. // @require https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js
  21. // @require https://gf.qytechs.cn/scripts/469717-nxu%E5%82%A8%E5%AD%98%E5%BA%93/code/NXU%E5%82%A8%E5%AD%98%E5%BA%93.js?version=1215934
  22. // @require https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.7.0.min.js
  23. // @connect https://webvpn.nxu.edu.cn/*
  24. // @resource svg-logo https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/css/all.min.css
  25. // @noframes
  26. // ==/UserScript==
  27.  
  28.  
  29. //==脚本系统操作==
  30. function deleteAllVar(){
  31. while(GM_listValues().length > 0){
  32. GM_deleteValue(GM_listValues()[0]);
  33. }
  34. console.log("变量已清空!");
  35. }
  36. function deleteVar(varname){
  37. GM_deleteValue(varname);
  38. console.log("删除了一个变量:" + varname);
  39. }
  40. function setVar(varname, vardata){
  41. GM_setValue(varname, vardata);
  42. console.log("设置了一个变量:\n" + varname + " => " + vardata);
  43. }
  44. function showAllVar() {
  45. var all_value="";
  46. for (var i = -1; i <= GM_listValues().length; i++) {
  47. if (i == -1) {
  48. all_value += "\n=========这里是储存的变量=========\n\n";
  49. } else if (i == GM_listValues().length) {
  50. all_value += "\n=========/这里是储存的变量=========";
  51. } else {
  52. all_value += GM_listValues()[i]+":"+GM_getValue(GM_listValues()[i])+"\n";
  53. }
  54. }
  55. console.log(all_value);
  56. }
  57. //删除所有变量
  58. //deleteAllVar();
  59.  
  60. //删除变量
  61. //deleteVar("news_goals");
  62.  
  63. //设置变量
  64. //setVar("date", "2022-12-25");
  65.  
  66. //输出所有储存的变量
  67. showAllVar();
  68.  
  69. //绑定到控制台
  70. unsafeWindow.deleteAllVar = deleteAllVar;
  71. unsafeWindow.deleteVar = deleteVar;
  72. unsafeWindow.setVar = setVar;
  73. unsafeWindow.showAllVar = showAllVar;
  74. unsafeWindow.GM_xmlhttpRequest = GM_xmlhttpRequest;
  75. //==/脚本系统操作==
  76.  
  77.  
  78. //==需要调用的函数==
  79.  
  80. //关闭窗口
  81. function closeWindow() {
  82. try {
  83. window.opener = window;
  84. var win = window.open("", "_self");
  85. win.close();
  86. top.close();
  87. } catch (error) {
  88. console.log("关闭窗口:失败\n错误信息:"+error);
  89. }
  90. }
  91.  
  92. //随机数
  93. function random(min, max){
  94. return parseInt(Math.random()*(max-min+1)+min,10);
  95. }
  96.  
  97. //等待执行
  98. function justWait(min, max, log = true){
  99. var waitmsg,waittime;
  100. if (max == 0) {
  101. waittime = min;
  102. waitmsg = "==等待了:"+(waittime / 1000)+" 秒==";
  103. } else {
  104. waittime = random(min, max);
  105. waitmsg = "==随机等待了:"+(waittime / 1000)+" 秒==";
  106. }
  107. return new Promise(function (resolve, reject) {
  108. setTimeout(function () {
  109. if (log) {
  110. console.log(waitmsg);
  111. }
  112. resolve();
  113. }, waittime);
  114. });
  115. }
  116.  
  117. //toast输出
  118. function createToast(id, mes, time = 5) {
  119. const notifications = document.querySelector('.notifications');
  120. const toastDetails = {
  121. success:{
  122. icon: 'fa-circle-check',
  123. text: 'Success: This is a success toast.'
  124. },
  125. error:{
  126. icon: 'fa-circle-xmark',
  127. text: 'Error: This is a error toast.'
  128. },
  129. warning:{
  130. icon: 'fa-circle-exclamation',
  131. text: 'Warning: This is a warning toast.'
  132. },
  133. info:{
  134. icon: 'fa-circle-info',
  135. text: 'Info: This is a info toast.'
  136. }
  137. };
  138. if (document.querySelector("style.i"+time.toString().replace(".", "\\."))){
  139. document.querySelector("style.i"+time.toString().replace(".", "\\.")).innerHTML = ".toast.i"+time+"::before{animation-duration: "+time+"s;}";
  140. } else {
  141. var style = document.createElement("style");
  142. style.className = "i"+time;
  143. style.innerHTML = ".toast.i"+time+"::before{animation-duration: "+time+"s;}";
  144. document.getElementsByTagName("head")[0].appendChild(style);
  145. }
  146. // console.log(id)
  147. const {icon, text} = toastDetails[id];
  148. let txt;
  149. if (mes == "" || mes == null || typeof(mes) == "undefined"){
  150. txt = text;
  151. } else {
  152. txt = mes;
  153. }
  154. const toast = document.createElement('li') // 创建li元素
  155. toast.setAttribute("time", time);
  156. toast.setAttribute("style", "::before{animation-duration: "+time+"}")
  157. toast.className = `toast ${id} i${time}` // 为li元素新增样式
  158. toast.innerHTML = `
  159. <div class="column">
  160. <i class="fa-solid ${icon}"></i>
  161. <span>${txt}</span>
  162. </div>
  163. <i class="fa-solid fa-xmark" onClick="removeToast(this.parentElement)"></i>`
  164. notifications.appendChild(toast) // 添加元素到 notifications ul
  165. // 隐藏toast
  166. if (time != 0){
  167. toast.timeoutId = setTimeout(()=> removeToast(toast), time * 1000);
  168. }
  169. }
  170.  
  171. //toast移除
  172. function removeToast(toast) {
  173. toast.classList.add('hide')
  174. if( toast.timeoutId) clearTimeout(toast.timeoutId) // 清楚setTimeout
  175. // 移除li元素
  176. setTimeout(() => {
  177. toast.remove()
  178. },500)
  179. }
  180.  
  181. //创建XHR
  182. function createXHR() {
  183. var xmlHttp;
  184. try {
  185. // Firefox, Opera 8.0+, Safari
  186. xmlHttp = new XMLHttpRequest();
  187. }
  188. catch (e) {
  189. // Internet Explorer
  190. try {
  191. xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
  192. } catch (e) {
  193. try {
  194. xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  195. } catch (e) {
  196. console.log("您的浏览器不支持AJAX!");
  197. return false;
  198. }
  199. }
  200. }
  201. return xmlHttp;
  202. }
  203.  
  204. function titleChange(dom) {
  205. //console.log("更改视图...")
  206. if (dom.id == "plugin-settings") {
  207. //document.querySelector(".anchor__item.is-active").classList.remove("is-active");
  208. //dom.classList.add("is-active");
  209. //var scrollableDiv = document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__view");
  210. //var contentDiv = document.querySelector("div#plugin-settings-content");
  211. //document.querySelector("div#plugin-settings-content").scrollIntoView({ behavior: 'auto', inline: 'center' });
  212. let div = document.querySelector("div#plugin-settings-content");
  213. let div_parent = document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap");
  214. document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap").scrollBy(0, div.getBoundingClientRect().top - div_parent.getBoundingClientRect().top)
  215. } else {
  216. //dom.classList.add("is-active");
  217. //document.querySelector("div.anchor__item#plugin-settings").classList.remove("is-active");
  218. }
  219. }
  220.  
  221. //绑定
  222. unsafeWindow.createToast = createToast;
  223. unsafeWindow.removeToast = removeToast;
  224. unsafeWindow.window.close = window.close;
  225. unsafeWindow.titleChange = titleChange;
  226. unsafeWindow.titleChange = titleChange;
  227. unsafeWindow.GM_xmlhttpRequest = GM_xmlhttpRequest;
  228. //==/需要调用的函数==
  229.  
  230.  
  231. //==预关闭==
  232. if (!$("title").length){
  233. if (GM_getValue("auto-close")) {
  234. window.close();
  235. } else {
  236. return;
  237. }
  238. }
  239. //==/预关闭==
  240.  
  241.  
  242. //==常量==
  243. const url = window.location.href;
  244. const type = $("title").text();
  245. const load_message = {"loading tesseract core":"核心加载","initializing tesseract":"初始化","loading language traineddata":"加载语言训练数据","initializing api":"初始化接口","recognizing text":"识别验证码"};
  246. //==/常量==
  247.  
  248.  
  249. //==开始==
  250. console.log("插件运行...");
  251.  
  252. //添加css样式
  253. GM_addStyle(css_content);
  254. GM_addStyle(GM_getResourceText("svg-logo").replace(/\.\.\/webfonts/g, "https://cdn.bootcdn.net/ajax/libs/font-awesome/6.2.1/webfonts"));
  255.  
  256. //插入toast列表
  257. var ul = document.createElement("ul");
  258. ul.className = "notifications";
  259. $("body").append(ul);
  260. //createToast("success", "测试消息", 0);
  261.  
  262. //自动关闭处理
  263. if (url == "https://webvpn.nxu.edu.cn/wengine-vpn/failed") {
  264. if ($("body").html().indexOf("http://ids.nxu.edu.cn/authserver/login?service=https%3A%2F%2Fwebvpn.nxu.edu.cn%2Flogin%3Fcas_login%3Dtrue")) {
  265. //location.href = "https://webvpn.nxu.edu.cn"
  266. createToast("warning", "好像出错了?<br>刷新试试吧", 5);
  267. }
  268. } else if (($("body").html().indexOf("啊呀,服务器开小差了。3秒后自动返回上一页") != -1)
  269. || ($("body").html().indexOf("出错啦!该网站无法访问!") != -1)
  270. || (url.indexOf("/login.action") != -1 && url != "https://jwgl.nxu.edu.cn/login.action")){
  271. if (GM_getValue("auto-close")) {
  272. window.close();
  273. } else {
  274. return;
  275. }
  276. } else if (url.indexOf("/index.action?wrdrecordvisit") != -1) {
  277. if (type == "宁夏大学教务管理信息系统") {
  278. if (GM_getValue("auto-close")) {
  279. window.close();
  280. }
  281. let div = document.createElement("div");
  282. div.setAttribute("style", "z-index: 9999;padding: 2em 3em;white-space: nowrap;;font-size: 16px;position: fixed;top: 50%;left: 50%;transform: translate(-50%,-50%);border-radius: 10px;border: 1px white solid;background: #49d3ef;background: -webkit-linear-gradient(to left, #49d3ef, #016ba9);background: linear-gradient(to right bottom, #49d3ef, #016ba9);display: flex;flex-direction: column;align-items: center;color: white;justify-content: center;");
  283. div.innerHTML = jwgl_error;
  284. $("body").append(div);
  285. GM_addElement(document.querySelector("div#control-button"), "button", {textContent: '立即跳转', onclick: "location.href = 'https\:\/\/jwgl.nxu.edu.cn'", style: "height: auto;margin: 0.5em 1em;padding: 0.5em 1em;border: 1px white solid;border-radius: 4px;font-weight: bold;color: white;background:#2193b0;background: -webkit-linear-gradient(to right bottom, #6dd5ed, #2193b0);background: linear-gradient(to right bottom, #6dd5ed, #2193b0);"});
  286. }
  287. }
  288.  
  289. //网页判断
  290. if (url == "https://jwgl.nxu.edu.cn/index.action" || url == "https://jwgl.nxu.edu.cn/login.action" ) {
  291. console.log("检测到教务系统登录(不可用)页面");
  292. //自动登录(不可用)
  293. if (!GM_getValue("auto-login") || GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) {
  294. return;
  295. }
  296. createToast("info", "自动登录(不可用)...", 5);
  297. //自动识别验证码
  298. Tesseract.recognize(
  299. 'https://jwgl.nxu.edu.cn/captcha/image.action',
  300. 'eng',
  301. { logger: m => load_message[m.status] ? (createToast("info", load_message[m.status], 1)) : (null) }
  302. ).then(({ data: { text } }) => {
  303. jwglLogin(text);
  304. })
  305. } else if (url.indexOf("https-443") != -1) {
  306. if (document.getElementsByTagName("h1")[0] && document.getElementsByTagName("h1")[0].innerHTML) {
  307. if (document.getElementsByTagName("h1")[0].innerHTML == 'An error occurred.') {
  308. console.log("检测到服务器错误页面");
  309. if (GM_getValue("auto-close")) {
  310. window.close();
  311. } else {
  312. return;
  313. }
  314. }
  315. } else if (type == "宁夏大学教务管理信息系统"){
  316. console.log("宁夏大学教务管理信息系统页面");
  317. console.log("等待800ms");
  318.  
  319. if (document.getElementsByName("loginForm.name")[0]) {
  320. if (GM_getValue("auto-close")) {
  321. window.close();
  322. }
  323. return;
  324. }
  325.  
  326. /*
  327. createToast("info", "自动登录(不可用)...", 5);
  328. //自动识别验证码
  329. Tesseract.recognize(
  330. url.replace(/index\.action.+/, "captcha/image.action?vpn-1"),
  331. 'eng',
  332. { logger: m => load_message[m.status] ? (createToast("info", load_message[m.status], 1)) : (null) }
  333. ).then(({ data: { text } }) => {
  334. console.log(1)
  335. jwglLogin(text);
  336. })
  337. */
  338. //成功进入
  339. jwgl();
  340.  
  341. }
  342. } else if (url.indexOf("login") != -1){
  343. console.log("疑似登录(不可用)页面,确认中...");
  344. if (document.querySelector("title").innerHTML.indexOf("503 Service Temporarily Unavailable") != -1) {
  345. location.reload();
  346. }
  347. if (!document.querySelector(".auth_tab")) {
  348. return;
  349. }
  350. console.log("登录(不可用)页面");
  351. if (GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) {
  352. return;
  353. }
  354. //自动登录(不可用)
  355. if (GM_getValue("auto-login")) {
  356. console.log("自动登录(不可用)...");
  357. createToast("info", "自动登录(不可用)...", 5);
  358. if (document.querySelector("#msg.auth_error")) {
  359. createToast("error", "输入的学号密码有误", 5);
  360. return;
  361. }
  362. document.querySelector("input#username").value = GM_getValue("username");
  363. document.querySelector("input#password").value = GM_getValue("password");
  364. document.querySelector("button.auth_login_btn").click();
  365. } else {
  366. return;
  367. }
  368. } else if (url == "https://webvpn.nxu.edu.cn/" || url == "https://webvpn.nxu.edu.cn"){
  369. console.log("资源访问控制系统首页");
  370. resourceIndex();
  371. } else if (type == "宁夏大学教务管理信息系统"){
  372. console.log("宁夏大学教务管理信息系统页面");
  373. console.log("等待800ms");
  374. if (document.getElementsByName("loginForm.name")[0]) {
  375. if (GM_getValue("auto-close")) {
  376. window.close();
  377. }
  378. return;
  379. }
  380. //成功进入
  381. jwgl();
  382. }
  383.  
  384. async function jwglLogin(text) {
  385. document.getElementsByName("loginForm.captcha")[0].onfocus();
  386. //document.querySelector("input#textfield.loginput").value = "";
  387. //document.querySelector("input#textfield2.loginput").value = "";
  388. document.querySelector("input#textfield.loginput").value = GM_getValue("username");
  389. document.querySelector("input#textfield2.loginput").value = GM_getValue("password");
  390. document.querySelector("input#textfield3.loginput").value = text;
  391. document.querySelector("input#submitButton").click();
  392. }
  393.  
  394. async function resourceIndex() {
  395. //等待标签加载完毕
  396. while(true) {
  397. if (document.querySelector("div.el-scrollbar__view") && document.querySelector("div.el-scrollbar__view").innerHTML) {
  398. break;
  399. }
  400. await justWait(100, 0);
  401. }
  402. GM_setValue("autoLogining", false);
  403. var div_title = document.querySelector("div.el-scrollbar__view");
  404. var div_setting_title = document.createElement("div");
  405. div_setting_title.innerHTML = "插件设置";
  406. div_setting_title.classList.add("anchor__item");
  407. div_setting_title.id = "plugin-settings";
  408. div_title.appendChild(div_setting_title);
  409. var div_settings = document.createElement("div");
  410. div_settings.innerHTML = settings_div;
  411. div_settings.id = "plugin-settings-content";
  412. document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__view").appendChild(div_settings);
  413. var div_option = document.querySelectorAll("div.anchor__item");
  414. for (let i = 0; i < div_option.length; i++) {
  415. div_option[i].setAttribute("onclick", "titleChange(this)");
  416. }
  417. document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap").onscroll = () => {
  418. let div = document.querySelector("div#plugin-settings-content");
  419. let div_parent = document.querySelector("div.portal-content__block").querySelector(".el-scrollbar__wrap");
  420. if (div.getBoundingClientRect().top <= div_parent.getBoundingClientRect().top) {
  421. document.querySelector("div.anchor__item#plugin-settings").classList.add("is-active");
  422. } else {
  423. document.querySelector("div.anchor__item#plugin-settings").classList.remove("is-active");
  424. }
  425. }
  426. var button = document.querySelector("#reflash-user-info");
  427. var input_username = document.querySelector("input#username");
  428. var input_password = document.querySelector("input#password");
  429. if (GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) {
  430. input_username.value = "";
  431. input_password.value = "";
  432. } else {
  433. input_username.value = GM_getValue("username");
  434. input_password.value = GM_getValue("password");
  435. }
  436. reflashUserInfoCheck()
  437. try {
  438. // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
  439. button.addEventListener("click", function(){
  440. reflashUserInfo();
  441. }, false);
  442. input_username.addEventListener("input", function(){
  443. reflashUserInfoCheck();
  444. }, false);
  445. input_password.addEventListener("input", function(){
  446. reflashUserInfoCheck();
  447. }, false);
  448. } catch (error) {
  449. try {
  450. // IE8.0及其以下版本
  451. button.attachEvent("onclick", function(){
  452. reflashUserInfo();
  453. }, false);
  454. input_username.addEventListener("oninput", function(){
  455. reflashUserInfoCheck();
  456. }, false);
  457. input_password.addEventListener("oninput", function(){
  458. reflashUserInfoCheck();
  459. }, false);
  460. } catch (error) {
  461. // 早期浏览器
  462. alert("错误: 按钮绑定事件失败\n很抱歉,该脚本并不适合您的浏览器\n请尝试安装最新版Edge、Chrome、FireFox、Opera、Safari或其他浏览器后获得支持");
  463. return;
  464. }
  465. }
  466. var input_switch_total = document.querySelectorAll("label.switch");
  467. for (let i = 0; i < input_switch_total.length; i++) {
  468. var input_switch = input_switch_total[i].querySelector("input");
  469. input_switch.checked = GM_getValue(input_switch.id);
  470. try {
  471. // Chrome、FireFox、Opera、Safari、IE9.0及其以上版本
  472. input_switch.addEventListener("input", function(){
  473. switchHandle(this);
  474. }, false);
  475. } catch (error) {
  476. try {
  477. // IE8.0及其以下版本
  478. input_switch.addEventListener("oninput", function(input_switch){
  479. switchHandle(this);
  480. }, false);
  481. } catch (error) {
  482. // 早期浏览器
  483. alert("错误: 按钮绑定事件失败\n很抱歉,该脚本并不适合您的浏览器\n请尝试安装最新版Edge、Chrome、FireFox、Opera、Safari或其他浏览器后获得支持");
  484. return;
  485. }
  486. }
  487. }
  488. }
  489.  
  490. function reflashUserInfo() {
  491. var warning = document.querySelectorAll("p.warning");
  492. for (let i = 0; i < warning.length; i++) {
  493. warning[i].style.display = "none";
  494. }
  495. var username = document.querySelector("input#username").value;
  496. var password = document.querySelector("input#password").value;
  497. //console.log(username);
  498. var pass = true;
  499. if (username == null || username == "") {
  500. document.querySelector("p.warning#username-empty").style.display = "block";
  501. pass = false;
  502. } else if (!/^1\d{9}\d$/.test(username)) {
  503. console.log(username);
  504. document.querySelector("p.warning#username-error").style.display = "block";
  505. pass = false;
  506. }
  507. if (password == null || password == "") {
  508. document.querySelector("p.warning#password-empty").style.display = "block";
  509. }
  510. if (pass) {
  511. //console.log("pass");
  512. GM_setValue("username", username);
  513. GM_setValue("password", password);
  514. createToast("success", "账号设置成功!", 2);
  515. document.querySelector("#reflash-user-info").disabled = true;
  516. }
  517. }
  518.  
  519. function reflashUserInfoCheck() {
  520. var username = document.querySelector("input#username").value;
  521. var password = document.querySelector("input#password").value;
  522. if (GM_getValue("username") == undefined || GM_getValue("username") == "" || GM_getValue("username") == null || GM_getValue("password") == undefined || GM_getValue("password") == "" || GM_getValue("password") == null) {
  523. return;
  524. }
  525. //console.log(username)
  526. //console.log(password)
  527. if (username == GM_getValue("username") && password == GM_getValue("password")) {
  528. document.querySelector("#reflash-user-info").disabled = true;
  529. } else {
  530. document.querySelector("#reflash-user-info").disabled = false;
  531. }
  532. }
  533.  
  534. function switchHandle(input) {
  535. GM_setValue(input.id, input.checked);
  536. var message = input.parentNode.parentNode.querySelector("p").innerHTML;
  537. if (input.checked) {
  538. message += "&nbsp;&nbsp;&nbsp;&nbsp;开";
  539. } else {
  540. message += "&nbsp;&nbsp;&nbsp;&nbsp;关";
  541. }
  542. createToast("info", message, 2);
  543. }
  544.  
  545. async function jwgl() {
  546. while (true) {
  547. if ($("iframe#menuIfr").length && $("iframe#menuIfr").contents().find("table") && $("iframe#menuIfr").contents().find("table").html()) {
  548. break;
  549. }
  550. await justWait(1000, 0);
  551. }
  552. $("body").css("overflow","hidden");
  553. var table_main = $("iframe#menuIfr").contents().find("td[valign=top]");
  554. table_main.append(jwgl_table_title("实用工具", "tool"));
  555. var table_title = $("iframe#menuIfr").contents().find("table#tool");
  556. table_main.append(jwgl_table_content("课表生成", "curriculum"));
  557. $("iframe#menuIfr").contents().find("a#curriculum").click(function () {
  558. curriculum();
  559. });
  560. table_main.append(jwgl_table_content("课表美化", "curriculum-beautification"));
  561. $("iframe#menuIfr").contents().find("a#curriculum-beautification").click(function () {
  562. curriculumBeautification();
  563. });
  564. }
  565.  
  566. async function curriculum() {
  567. var docu = $("iframe#menuIfr")[0].contentWindow.document;
  568. if (!$("iframe#main").contents().find("iframe")[0] || $("iframe#main").contents().find("iframe")[0].src.indexOf("courseTableForStd.action") == -1) {
  569. if (docu.querySelector("#menuTreenodeIcon4").src == "https://jwgl.nxu.edu.cn/static/images/tree/plus.gif") {
  570. docu.querySelector("#menuTreeLink4").click();
  571. }
  572. while (true) {
  573. if (docu.querySelector("#menuTreeLink6")) {
  574. break;
  575. }
  576. await justWait(500,0);
  577. }
  578. docu.querySelector("#menuTreeLink6").click();
  579. while (true) {
  580. if ($("iframe#main").contents().find("iframe").contents().find("div").html()) {
  581. break;
  582. }
  583. await justWait(500,0);
  584. }
  585. createToast("info", "请确认学期后再次点击按钮", 3);
  586. return;
  587. }
  588. const $$ = (message)=>{return $("iframe#main").contents().find("iframe").contents().find(message)};
  589. if (!$$("table.listTable").length) {
  590. createToast("error", "无课表显示!", 3);
  591. return;
  592. }
  593. $$("td > div").each(function() {
  594. var div = $(this);
  595. //div.html(div.attr('title'));
  596. var content = div.attr('title');
  597. content = content.split(/[ \n\r]+/);
  598. (content.length == 3) ? (content.splice(1, 0, "未定")) : (null);
  599. var content_array = [];
  600. for (let i = 0; i < content.length; i += 4) {
  601. content_array.push(content.slice(i, i + 4));
  602. }
  603. console.log(content_array);
  604. });
  605. }
  606.  
  607. async function curriculumBeautification() {
  608. var docu = $("iframe#menuIfr")[0].contentWindow.document;
  609. if (!$("iframe#main").contents().find("iframe")[0] || $("iframe#main").contents().find("iframe")[0].src.indexOf("courseTableForStd.action") == -1) {
  610. if (docu.querySelector("#menuTreenodeIcon4").src == "https://jwgl.nxu.edu.cn/static/images/tree/plus.gif") {
  611. docu.querySelector("#menuTreeLink4").click();
  612. }
  613. while (true) {
  614. if (docu.querySelector("#menuTreeLink6")) {
  615. break;
  616. }
  617. await justWait(500,0);
  618. }
  619. docu.querySelector("#menuTreeLink6").click();
  620. while (true) {
  621. if ($("iframe#main").contents().find("iframe").contents().find("div").html()) {
  622. break;
  623. }
  624. await justWait(500,0);
  625. }
  626. }
  627. const $$ = (message)=>{return $("iframe#main").contents().find("iframe").contents().find(message)};
  628. if (!$$("table.listTable").length) {
  629. createToast("error", "无课表显示!", 3);
  630. return;
  631. }
  632. if ($$("table.optimized").length) {
  633. createToast("info", "已美化!", 3);
  634. return;
  635. }
  636. $$("body").html($$("body").html().replace(".noneprint{\n\tdisplay:none\n} \n\n",""))
  637. $$("table.listTable").addClass('optimized');
  638. $("iframe#main").attr("scrolling", "no");
  639. $("iframe#main").contents().find("iframe").attr("scrolling", "auto");
  640. $$("table").css("margin-bottom", "3em");
  641. $$("tr").attr("height", "auto");
  642. $$("tr").css("min-height", "45px");
  643. $$("td > div").each(function() {
  644. var div = $(this);
  645. //div.html(div.attr('title'));
  646. div.css("height", "auto");
  647. div.css("padding", "1em 0.5em 0");
  648. var content = div.attr('title');
  649. content = content.split(/(?<!\d|\[|\]|\(|\))[ \n\r]+(?<!\d|\[|\]|\(|\))/);
  650. (content.length == 3) ? (content.splice(1, 0, "未定")) : (null);
  651. var content_array = [];
  652. for (let i = 0; i < content.length; i += 4) {
  653. content_array.push(content.slice(i, i + 4));
  654. }
  655. console.log(content_array);
  656. div.css("display", "flex");
  657. div.css("flex-direction", "column");
  658. div.css("justify-content", "center");
  659. div.css("align-items", "center");
  660. div.css("text-align", "center");
  661. div.html("");
  662. for (let i = 0; i < content_array.length; i++) {
  663. (content_array.length > 1) ? div.append(jwgl_class(content_array[i], i)) : div.append(jwgl_class(content_array[i]))
  664. }
  665. });
  666. }
  667.  
  668. function isIframeChange() {
  669. var elemIfram = document.querySelector("iframe#main");
  670. if (window.MutationObserver || window.webkitMutationObserver) {
  671. // chrome
  672. var callback = function(mutations) {
  673. mutations.forEach(function() {
  674. iframeChange();
  675. });
  676. };
  677. var observer
  678. if (window.MutationObserver) {
  679. observer = new MutationObserver(callback);
  680. } else {
  681. observer = new webkitMutationObserver(callback);
  682. }
  683. observer.observe(elemIfram, {
  684. subtree: true,
  685. attributes: true,
  686. attributeOldValue: true
  687. });
  688. } else if (elemIfram.addEventListener) {
  689. // Firefox, Opera and Safari
  690. elemIfram.addEventListener("DOMAttrModified", function(){iframeChange();}, false);
  691. } else if (elemIfram.attachEvent) {
  692. // Internet Explorer
  693. elemIfram.attachEvent("onpropertychange", function(){iframeChange();});
  694. }
  695. }
  696.  
  697. function iframeChange() {
  698. console.log("111");
  699. }
  700.  
  701. async function needLogin() {
  702. if (new Date().getTime() - GM_getValue("needLoginCheck") < 60 * 10 * 1000) {
  703. return;
  704. }
  705. GM_setValue("needLoginCheck", new Date().getTime());
  706. GM_setValue("autoLogining", true);
  707. GM_xmlhttpRequest({
  708. method: "GET",
  709. url: "https://webvpn.nxu.edu.cn/",
  710. onload: function(response) {
  711. console.log(response.finalUrl);
  712. if (response.finalUrl.indexOf("login") != -1) {
  713. console.log(GM_getValue("autoLogining"))
  714. var tab = GM_openInTab("https://webvpn.nxu.edu.cn/");
  715. var listener = GM_addValueChangeListener("autoLogining", function(key, oldValue, newValue, remote) {
  716. console.log(111)
  717. tab.close();
  718. GM_removeValueChangeListener(listener);
  719. });
  720. }
  721. }
  722. });
  723. await justWait(1000 * 60 * 10, 0);
  724. }
  725.  
  726. document.onvisibilitychange = ()=>{
  727. if (document.visibilityState == "visible"){
  728. needLogin();
  729. }
  730. }
  731.  
  732.  
  733.  

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址