// ==UserScript== // @name BIT-乐学-修改侧边栏课程-GUI // @namespace http://tampermonkey.net/ // @version 0.1.2 // @description 修改侧边栏显示的课程 // @license GPL-3.0-or-later // @supportURL https://github.com/YDX-2147483647/BIT-enhanced/issues // @author CJJ // @match *://lexue.bit.edu.cn/* // @grant GM_getValue // @grant GM_setValue // @grant GM_registerMenuCommand // @downloadURL none // ==/UserScript== (async function () { 'use strict' /* global GM_getValue */ /* global GM_setValue */ /* global GM_registerMenuCommand */ let dragsrc = null let shown_courses = await GM_getValue('lexue_shown_courses') let hidden_courses = await GM_getValue('lexue_hidden_courses') const popup_cover = document.createElement('div') const popup = document.createElement('div') popup_cover.style = 'width:100%;height:100%;background-color:rgba(0,0,0,0.6);position:fixed;inset:0px;z-index:2000' function rewrite_sidebar (shown_courses) { const current_id = (document.querySelector('[data-key="coursehome"].active_tree_node')?.href?.match(/(?<=id=)\w+/) || [])[0] const mycourses = document.querySelector('li:has([data-key="mycourses"])') const sidebar_course_list = mycourses.parentNode let node = mycourses.nextSibling while (node) { node.parentNode.removeChild(node) node = mycourses.nextSibling } for (let i = 0; i < shown_courses.length; i++) { const classList = (current_id === shown_courses[i][0] ? ['list-group-item-action active active_tree_node ', 'font-weight-bold '] : ['', '']) sidebar_course_list.innerHTML += `
  • ${shown_courses[i][1]}
  • ` } } function openPopup () { popup.style = 'background-color:white;color:black;box-shadow:rgb(153,153,153) 0px 0px 2px;transform:translate(-50%,-50%);position:fixed;border:3px solid rgba(0,0,0,0.6);font-size:16px;overflow:hidden;z-index:3000;left:50%;top:50%;width:70%;text-align:center;' popup.innerHTML = ` 通过拖动来归类和排序
    显示的课程
    隐藏的课程
    ` popup.querySelector('#close_popup').onclick = () => closePopup() popup.querySelector('#rewrite_sidebar').onclick = () => { closePopup() shown_courses = [] hidden_courses = [] const shown_lis = popup.querySelectorAll('#shown_courses>li') const hidden_lis = popup.querySelectorAll('#hidden_courses>li') for (let i = 0; i < shown_lis.length; i++) { shown_courses.push([shown_lis[i].dataset.id, shown_lis[i].innerText]) } for (let j = 0; j < hidden_lis.length; j++) { hidden_courses.push([hidden_lis[j].dataset.id, hidden_lis[j].innerText]) } GM_setValue('lexue_shown_courses', shown_courses) GM_setValue('lexue_hidden_courses', hidden_courses) rewrite_sidebar(shown_courses) } popup.querySelector('#shown_courses').addEventListener('dragover', function (e) { e.preventDefault() }) popup.querySelector('#shown_courses').addEventListener('drop', function (e) { e.preventDefault() this.append(dragsrc) }) popup.querySelector('#hidden_courses').addEventListener('dragover', function (e) { e.preventDefault() }) popup.querySelector('#hidden_courses').addEventListener('drop', function (e) { e.preventDefault() this.append(dragsrc) }) for (let i = 0; i < shown_courses.length; i++) { const shown_li = document.createElement('li') shown_li.setAttribute('data-id', shown_courses[i][0]) shown_li.draggable = 'true' shown_li.addEventListener('dragstart', function (e) { dragsrc = this }) shown_li.addEventListener('dragover', function (e) { e.preventDefault() }) shown_li.addEventListener('drop', function (e) { e.stopPropagation() if (this !== dragsrc) { if (this.parentNode === dragsrc.parentNode && this.offsetTop > dragsrc.offsetTop) { this.parentNode.insertBefore(dragsrc, this.nextSibling)// if this.nextSibling===null insert as the last child. } else { this.parentNode.insertBefore(dragsrc, this) } } }) shown_li.innerHTML = `
    ${shown_courses[i][1]}
    ` popup.querySelector('#shown_courses').append(shown_li) } for (let j = 0; j < hidden_courses.length; j++) { const hidden_li = document.createElement('li') hidden_li.setAttribute('data-id', hidden_courses[j][0]) hidden_li.draggable = 'true' hidden_li.addEventListener('dragstart', function (e) { dragsrc = this }) hidden_li.addEventListener('dragover', function (e) { e.preventDefault() }) hidden_li.addEventListener('drop', function (e) { e.stopPropagation() if (this !== dragsrc) { if (this.parentNode === dragsrc.parentNode && this.offsetTop > dragsrc.offsetTop) { this.parentNode.insertBefore(dragsrc, this.nextSibling)// if this.nextSibling===null insert as the last child. } else { this.parentNode.insertBefore(dragsrc, this) } } }) hidden_li.innerHTML = `
    ${hidden_courses[j][1]}
    ` popup.querySelector('#hidden_courses').append(hidden_li) } document.body.append(popup_cover) document.body.append(popup) } function closePopup () { document.body.removeChild(popup_cover) document.body.removeChild(popup) } function reload_courses () { const xhr = new XMLHttpRequest() xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { shown_courses = [] hidden_courses = [] const a = new DOMParser().parseFromString(xhr.responseText, 'text/html').querySelectorAll("a[href*='lexue.bit.edu.cn/user/view.php']") for (let i = 0; i < a.length; i++) { shown_courses.push([a[i].href.match(/(?<=course=)\w+/)[0], a[i].innerText]) } openPopup() } } xhr.open('GET', document.querySelector("[href*='lexue.bit.edu.cn/user/profile.php?id=']").href + '&showallcourses=1', true) xhr.send() } if (shown_courses || hidden_courses) { rewrite_sidebar(shown_courses) } else { reload_courses() } GM_registerMenuCommand('更新课程并修改侧边栏', function () { if (!popup.parentNode) { reload_courses() } }) GM_registerMenuCommand('仅修改侧边栏', function () { if (!popup.parentNode) { openPopup() } }) })()