// ==UserScript== // @name Bb 增强 | Blackboard Enhanced // @namespace Violentmonkey Scripts // @match https://pibb.scu.edu.cn/webapps/portal/* // @match https://pibb.scu.edu.cn/webapps/assignment/gradeAssignmentRedirector* // @exclude https://pibb.scu.edu.cn/webapps/bb-social-learning-BBLEARN/* // @exclude https://pibb.scu.edu.cn/webapps/assignment* // @grant none // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_notification // @version 1.8 // @author sitdownkevin // @description 2023/3/26 16:07:00 // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 作业批改增强 if (window.location.href.startsWith('https://pibb.scu.edu.cn/webapps/assignment/gradeAssignmentRedirector')) { setTimeout(() => { console.log('进入作业批改模式'); pageOptimal(); scoreCount(); addMemo(); }, 3000); // 优化页面布局 => 自动打开评价标签 & 删除部分元素 function pageOptimal() { console.log("Loading Page Optimization!"); document.querySelector("#currentAttempt_gradeDataPanel").style.display = ''; // 展开评价框 // 需要删除的元素 const waitList = [ document.querySelector("#currentAttempt_feedback_wrapper > h4"), // "给学习者的反馈" document.querySelector("#feedbacktext_tbl > tbody > tr > td > span"), // "对于工具栏,请按 ALT+F10 (PC) 或 ALT+FN+F10 (Mac)。" document.querySelector("#currentAttempt_gradeDataPanelLink") // 折叠按钮 ]; // 删除元素 for (let i=0; i { const pattern = /-\d+(\.\d+)?/g; return feedback.match(pattern); }; const computeGrade = (extractedArr, totalGrade) => { if (!extractedArr) {return totalGrade;} let grade = totalGrade; for (let i=0; i 填入之前的成绩 element_fillingLocation.value = lastGrade; } else { // 如果是第一次批改作业 => 填入满分 element_fillingLocation.value = totalGrade; } element_body.addEventListener('input', (e) => { feedback = e.target.innerHTML; extractedArr = extractNums(feedback); curGrade = computeGrade(extractedArr, totalGrade); element_fillingLocation.value = curGrade; }); } // 添加备忘录 function addMemo() { var element_target = document.querySelector("#currentAttempt_submission"); var memo_container = document.createElement("div"); memo_container.style.width = "100%"; memo_container.style.height = "400px"; memo_container.style.backgroundColor = "#DFF0F4"; element_target.parentNode.insertBefore(memo_container, element_target); var memo_content = document.createElement("div"); var memo_content_input = document.createElement("div"); memo_content.style.height = '320px'; memo_content.style.display = 'flex'; memo_content.style.justifyContent = 'center'; memo_content.style.alignItems = 'center'; memo_content_input.contentEditable = true; if (!GM_getValue("memo_content")) { GM_setValue("memo_content", '这是一个备忘录'); } memo_content_input.innerHTML = GM_getValue("memo_content"); memo_content_input.style.height = '90%'; memo_content_input.style.width = '95%'; memo_content_input.style.backgroundColor = "#FFFFFF"; memo_content_input.style.border = '1px solid #ccc'; memo_content_input.style.padding = '2px'; // 监听 “备忘录” 输入 memo_content_input.addEventListener('input', () => { // debug: console.log(memo_content_input.innerHTML); GM_setValue("memo_content", memo_content_input.innerHTML); }); memo_content.append(memo_content_input); memo_container.append(memo_content); var memo_clear = document.createElement("div"); var memo_clear_btn = document.createElement("button"); memo_clear.style.height = '30px'; memo_clear.style.position = "relative"; memo_clear_btn.style.backgroundColor = '#DADADA'; memo_clear_btn.style.border = '0 solid'; memo_clear_btn.style.width = '70px'; memo_clear_btn.style.height = '30px'; memo_clear_btn.style.position = "absolute"; memo_clear_btn.style.top = "50%"; memo_clear_btn.style.left = "50%"; memo_clear_btn.style.transform = "translate(-50%, -50%)"; memo_clear_btn.textContent = "清除"; // 监听 “清除” 按钮 memo_clear_btn.addEventListener("click", () => { console.log("Clear Button Clicked"); GM_setValue("memo_content", '这是一个备忘录'); memo_content_input.innerHTML = GM_getValue("memo_content"); }); memo_clear.append(memo_clear_btn); memo_container.append(memo_clear); }; }; // DDL催命鬼 if (window.location.href.startsWith('https://pibb.scu.edu.cn/webapps')) { var oringinal_todo_items, todo_items; setTimeout(() => { const cookie = document.cookie; var start_date = new Date(); var end_date = new Date(); end_date.setDate(end_date.getDate() + 28); const url = "https://pibb.scu.edu.cn/webapps/calendar/calendarData/selectedCalendarEvents"; const params = "?start=" + start_date.getTime() + "&end=" + end_date.getTime() + "&course_id=&mode=personal"; GM_xmlhttpRequest({ method: "GET", url: url + params, headers: { "Cookie": cookie, "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36", "Referer": "https://pibb.scu.edu.cn/webapps/calendar/viewMyBb?globalNavigation=false", "Accept": "*/*", "Sec-Fetch-Site": "same-origin" }, onload: (res) => { oringinal_todo_items = JSON.parse(JSON.stringify(JSON.parse(res.responseText), null, 2)); // debug: console.log(oringinal_todo_items); todo_items = extractItems(oringinal_todo_items); createContainer(); } }); }, 300); // 处理json文件: origin_todo_items => todo_items function extractItems(oringinal_todo_items) { var todo_items = []; for (let i=0; i { return Date.parse(a.deadline) - Date.parse(b.deadline); }); // 添加渐变颜色 const colorChoices = [ ['#ff4e4f', '#ff9d81'], ['#d14631', '#fabf12'], ['#ff2121', '#d14631'] ] const colorArr = generateGradientColors(colorChoices[2][0], colorChoices[2][1], todo_items.length); for (let i=0; i {console.log('Notification Clicled!')} }); }; const container_style = ` position: fixed; z-index: 10000; top: ${GM_getValue('container_style')['container_top']}; left: ${GM_getValue('container_style')['container_left']}; width: 290px; height: 300px; opacity: 0.9; pointer-events: auto; border-radius: 0; display: ${GM_getValue('checked', true) ? '': 'none'}; `; container.style.cssText = container_style; document.body.appendChild(container); // 创建滚动列表 const list = document.createElement('div'); const list_style = ` width: 100%; height: 80%; overflow-y: scroll; pointer-events: auto; border-radius: 15px; ::-webkit-scrollbar { width: 0; background: transparent; } `; // list.setAttribute('style', list_style); list.style.cssText = list_style; container.appendChild(list); // 创建行 for (let i=0; i { var xOffset = e.clientX - container.offsetLeft; var yOffset = e.clientY - container.offsetTop; // debug: console.log(xOffset, yOffset); var handleMouseMove = (e) => { container.style.left = (e.clientX - xOffset) + 'px'; container.style.top = (e.clientY - yOffset) + 'px'; } document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', function() { GM_setValue('container_style', { 'container_top': container.style.top, 'container_left': container.style.left }); document.removeEventListener('mousemove', handleMouseMove); }); }); } // 倒计时 function flashTime(countDown, i){ setInterval(() => { var now = new Date(); countDown.innerHTML = formatDuration(Date.parse(todo_items[i]['deadline']) - now.getTime()); }, 1000); } // 时间差转换: ms => x天x小时x分钟x秒 function formatDuration(ms) { const second = 1000; const minute = second * 60; const hour = minute * 60; const day = hour * 24; const days = Math.floor(ms / day); const hours = Math.floor((ms % day) / hour); const minutes = Math.floor((ms % hour) / minute); const seconds = Math.floor((ms % minute) / second); let result = ''; if (days > 0) { result += days + '天'; } if (hours > 0) { result += hours + '小时'; } if (minutes > 0) { result += minutes + '分钟'; } if (seconds > 0) { result += seconds + '秒'; } return result; } } })();