您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This userscript allows HKU students to show your current courses (in a semester) in a separate entry in HKU Moodle. By: Andrew Z, converted to userscript by q234rty
当前为
- // ==UserScript==
- // @name HKU moodle helper
- // @include http://moodle.hku.hk/*
- // @include https://moodle.hku.hk/*
- // @version 1.4.5
- // @description This userscript allows HKU students to show your current courses (in a semester) in a separate entry in HKU Moodle. By: Andrew Z, converted to userscript by q234rty
- // @author AENeuro, q234rty
- // @resource mystyle https://cdn.jsdelivr.net/gh/AENeuro/HKU-Moodle-Helper@2d0a17a/myStyle.css
- // @license CC BY-NC 4.0
- // @grant GM_getResourceText
- // @grant GM_addStyle
- // @grant GM_getValue
- // @grant GM_setValue
- // @namespace https://greasyfork.org/users/78076
- // ==/UserScript==
- globalThis.addFeedbackBox = function() {
- function showTextArea() {
- document.getElementById("helperFeedbackForm").classList.add("helper-shown")
- document.getElementById("helperFeedbackButton").insertAdjacentHTML("beforebegin", `
- <p id="helperFeedbackButton2" style="color: #AAAAAA;">You can also submit an issue or PR on
- <a href="https://github.com/AENeuro/HKU-Moodle-Helper" target="_blank">
- <span style="color: #AAAAAA;"><u>Github</u></span>
- </a>
- </p>
- `)
- document.getElementById("helperFeedbackButton").remove()
- }
- async function sendFeedback() {
- document.getElementById("helperFeedbackSend").disabled = true
- try {
- await request({
- url: " https://j8n6ydl8hd.execute-api.ap-southeast-1.amazonaws.com/create",
- method: "POST",
- body: document.getElementById("helperFeedbackInput").value
- })
- } catch (e) {
- alert("Network error")
- }
- document.getElementById("helperFeedbackForm").classList.remove("helper-shown")
- document.getElementById("helperFeedbackForm").insertAdjacentHTML("beforebegin", `
- <p style="color: #AAAAAA">Thank you for your feedback!</p>
- `)
- document.getElementById("helperFeedbackButton2").remove()
- }
- // initialization
- var version = GM_info.script.version;
- document.getElementsByClassName("course-of-sem-wrapper")[0].insertAdjacentHTML("beforeend", `
- <div class="helper-feedback">
- <p>Powered by HKU Moodle Helper ver. ${version}</p>
- <p id="helperFeedbackButton">Feedback</p>
- <div id="helperFeedbackForm" class="helper-hidden">
- <input id="helperFeedbackInput" type="text"/><br/>
- <button id="helperFeedbackSend">Send</button>
- </div>
- </div>
- `)
- document.getElementById("helperFeedbackButton").addEventListener("click", showTextArea)
- document.getElementById("helperFeedbackSend").addEventListener("click", sendFeedback)
- }
- globalThis.addMessageBox = function() {
- const messageBox = `
- <section class="helper-extension-persistent helper-message-box block_html block card mb-3" role="complementary" data-block="html" aria-labelledby="instance-330654-header">
- <div class="card-body p-3">
- <h5 class="card-title d-inline">Message from HKU Moodle Helper</h5>
- <div class="card-text content mt-3">
- <div class="no-overflow">
- <p><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">
- This is a message generated by the chrome extension <i>HKU Moodle Helper</i> that you intsalled.
- </span></p>
- <p><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">
- As many of you have noticed, moodle underwent renovation, and it's unclear just how it would affect the extension yet.
- </span></p>
- <p><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:black">
- The extension will still be maintained, provided it's still relevant in new semesters to come.
- In the meantime, please condider becoming a dev in <a href="https://github.com/AENeuro/HKU-Moodle-Helper" target="_blank">HKU Moodle Helper</a>.
- Any PR or suggestions are welcomed of course.
- </span></p>
- </div>
- <div class="footer"></div>
- </div>
- </div>
- </section>
- `
- document.getElementById("block-region-side-post").firstChild.insertAdjacentHTML("beforebegin", messageBox)
- }
- const request = obj => {
- return new Promise((resolve, reject) => {
- let xhr = new XMLHttpRequest();
- xhr.open(obj.method || "GET", obj.url);
- if (obj.headers) {
- Object.keys(obj.headers).forEach(key => {
- xhr.setRequestHeader(key, obj.headers[key]);
- });
- }
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- resolve(xhr.response);
- } else {
- reject(xhr.statusText);
- }
- };
- xhr.onerror = () => reject(xhr.statusText);
- xhr.send(JSON.stringify(obj.body));
- });
- };
- (function() {
- const my_css = GM_getResourceText("mystyle");
- GM_addStyle(my_css);
- // Note: every element that is to be removed during a clearing session
- // should be marked with a "helper-extension" classname
- // Otherwise it should be marked with "helper-extension-persistent"
- // Code splitting was done through globalThis (which was confined within ContentScript. Thus no pollutions were made)
- mainFunction()
- async function mainFunction() {
- await addCourseOfSem()
- globalThis.addFeedbackBox()
- globalThis.addMessageBox()
- }
- async function addCourseOfSem() {
- courseHTML = new Array()
- courseIDs = JSON.parse(GM_getValue("courseid", "[]"))
- //console.log(GM_getValue("courseid","[]"))
- clearAll()
- var courses = document.getElementsByClassName("coursebox")
- for (var i = 0; i < courses.length; i++) {
- currentCourseID = courses[i].dataset.courseid
- var included = false
- if (courseIDs) {
- included = courseIDs.includes(currentCourseID)
- }
- if (included) {
- //如果在列表中
- //复制element,存入数组
- courseHTML.push(courses[i].cloneNode(true))
- // Applies to all courses on the page that is in the list (in "my courses" section)
- courses[i].lastChild.lastChild.insertAdjacentHTML('beforebegin', `
- <button class="helper-extension helper-remove-button" id="removeCourse${currentCourseID}">
- Remove from this semester
- </button>
- `)
- document.getElementById("removeCourse" + currentCourseID).addEventListener("click", function(e) {
- removeCourse(e.target.id.slice(12), courseIDs)
- })
- } else {
- // Applies to all courses on the page that is not in the list (in "my courses" section)
- courses[i].lastChild.lastChild.insertAdjacentHTML('beforebegin', `
- <button class="helper-extension helper-add-button" id="addCourse${currentCourseID}">
- Add to this semester
- </button>
- `)
- document.getElementById("addCourse" + currentCourseID).addEventListener("click", function(e) {
- addCourse(e.target.id.slice(9), courseIDs)
- })
- }
- }
- var outerContainer = document.getElementById("frontpage-course-list")
- if (courseIDs && courseIDs.length) {
- //如果有课程
- outerContainer.insertAdjacentHTML('afterbegin', `
- <div class="helper-extension course-of-sem-wrapper">
- <h2>
- Course of this semester
- <div id="removeAll">×</button>
- </h2>
- <div id="courseOfSem" class="courses frontpage-course-list-enrolled has-pre has-post course-of-sem"></div>
- </div>
- `)
- document.getElementById("removeAll").addEventListener("click", function() {
- if (confirm("Sure you wanna remove all courses from this semester?")) {
- removeAll()
- }
- })
- } else {
- //没有课程
- outerContainer.insertAdjacentHTML('afterbegin', `
- <div class="helper-extension course-of-sem-wrapper">
- <h2>Course of this semester</h2>
- <p><i>Please click 'Add to this semester' on a course to bring it here.</i></p>
- </div>
- `)
- }
- var innerContainer = document.getElementById("courseOfSem")
- for (var j = 0; j < courseHTML.length; j++) {
- if (j % 2) {
- //注意这里是偶数 => 这里是不能整除2(i是奇数),但是在显示顺序上是“偶数”
- courseHTML[j].className = "coursebox clearfix even"
- } else {
- courseHTML[j].className = "coursebox clearfix odd"
- }
- // applies to all courses in this semester (in "course of this semester" section)
- currentCourseID = courseHTML[j].dataset.courseid
- courseHTML[j].insertAdjacentHTML('afterbegin', `
- <a id="removeCourseA${currentCourseID}" style="position: absolute; top: 5px; right: 5px; font-size: 25px; color: darkgrey; cursor: pointer">
- ×
- </a>
- `)
- innerContainer.appendChild(courseHTML[j])
- document.getElementById("removeCourseA" + currentCourseID).addEventListener("click", function(e) {
- removeCourse(e.target.id.slice(13), courseIDs)
- })
- }
- }
- // ======================================
- // Helper functions
- function clearAll() {
- var clearElements = document.getElementsByClassName("helper-extension")
- //必须倒序删除,因为HTMLCollection会因为remove方法动态变化
- for (var i = clearElements.length - 1; i >= 0; --i) {
- clearElements[i].remove()
- }
- }
- async function addCourse(courseCode, courseIDs) {
- if (courseIDs && courseIDs.length) {
- courseIDs.push(courseCode)
- } else {
- courseIDs = [courseCode]
- }
- //console.log(JSON.stringify(courseIDs))
- GM_setValue("courseid", JSON.stringify(courseIDs))
- mainFunction()
- }
- async function removeCourse(courseCode, courseIDs) {
- courseIDs = courseIDs.filter(function(value, index, arr) {
- return value !== courseCode;
- });
- GM_setValue("courseid", JSON.stringify(courseIDs))
- mainFunction()
- }
- async function removeAll() {
- GM_setValue("courseid", "[]")
- mainFunction()
- }
- })();