// ==UserScript== // @name 希冀平台移动端美化 // @namespace whu-cslabcg-prettier // @version 0.0.0 // @description 武汉大学计算机学院专业课一体化平台(cslabcg)移动端响应式美化:顶栏、课程选择页、在线作业目录 // @icon https://cslabcg.whu.edu.cn/images/cgicon.png // @match https://cslabcg.whu.edu.cn/* // @grant GM_addStyle // @run-at document-start // @license MIT // ==/UserScript== (function() { "use strict"; var s = new Set(); var _css = async (t) => { if (s.has(t)) return; s.add(t); ((c) => { if (typeof GM_addStyle === "function") GM_addStyle(c); else (document.head || document.documentElement).appendChild(document.createElement("style")).append(c); })(t); }; _css(":root{--cg-green:var(--theme-color,#00a185);--cg-green-dark:var(--theme-font,#005a5c);--cg-surface:#fff;--cg-border:#e3e7e6;--cg-text:#2b3a38;--cg-muted:#6c7a78;--cg-radius:12px;--cg-shadow:0 4px 16px #003c321f;--cg-shape:4px;--cg-ease-standard:cubic-bezier(.4, 0, .2, 1);--cg-ease-decel:cubic-bezier(0, 0, .2, 1);--cg-dur-short:.15s;--cg-dur-medium:.25s;--cg-elev-1:0 1px 2px 0 #00302824, 0 1px 3px 1px #00302814;--cg-elev-2:0 3px 1px -2px #00302833, 0 2px 2px 0 #00302824, 0 1px 5px 0 #0030281f;--cg-elev-8:0 5px 5px -3px #00302833, 0 8px 10px 1px #00302824, 0 3px 14px 2px #0030281f;--cg-state-hover:#00a18514;--cg-state-press:#00a18529;--cg-state-selected:#00a1851f;--cg-state-focus:#00a1851f}.cg-pretty-directory-toggle:focus-visible,.cg-pretty-courses a:focus-visible{outline:3px solid var(--cg-green);outline-offset:2px;border-radius:6px}#cgclientNAV{--cg-primary:var(--theme-color,#00a185);--cg-primary-dark:var(--theme-font,#005a5c);--cg-on-primary:#fff;--cg-state-hover:#ffffff14;--cg-state-focus:#ffffff1f;--cg-state-press:#ffffff1f;--cg-state-selected:#00a1851f;box-shadow:var(--cg-elev-2);position:relative}#cgclientNAV .navbar-brand{align-items:center;margin-right:16px;padding:0;display:flex}#cgclientNAV .navbar-brand img{width:auto;height:28px}#cgclientNAV .navbar-nav .nav-item{margin-left:0!important;padding:0 4px!important}#cgclientNAV .navbar-nav .nav-link{box-sizing:border-box;border-radius:var(--cg-shape);min-height:48px;color:var(--cg-on-primary);transition:background-color var(--cg-dur-short) var(--cg-ease-standard);background-color:#0000;border:0;align-items:center;gap:8px;padding:0 12px;font-size:14px;font-weight:500;line-height:1;display:inline-flex}#cgclientNAV .navbar-nav .nav-link svg{flex:none}#cgclientNAV .navbar-nav .nav-link:hover,#cgclientNAV .navbar-nav .nav-link:focus-visible{background-color:var(--cg-state-hover)}#cgclientNAV .navbar-nav .nav-link:active{background-color:var(--cg-state-press)}#cgclientNAV .navbar-nav .nav-item.current{position:relative}#cgclientNAV .navbar-nav .nav-item.current:after{content:\"\";background:var(--cg-on-primary);height:2px;position:absolute;bottom:0;left:0;right:0}#cgclientNAV .navbar-nav .nav-item.current>.nav-link{color:var(--cg-on-primary);font-weight:500}#cgclientNAV .dropdown-menu{border-radius:var(--cg-shape);background-color:var(--cg-surface);box-shadow:var(--cg-elev-8);z-index:1100;border:0;margin-top:8px;padding:8px 0;overflow:hidden}#cgclientNAV .dropdown-item,#cgclientNAV .nav-tabs .nav-link{box-sizing:border-box;min-height:48px;font:inherit;box-shadow:none;transition:background-color var(--cg-dur-short) var(--cg-ease-standard);background-color:#0000;align-items:center;padding:0 16px;font-size:14px;display:flex;color:var(--cg-text)!important}#cgclientNAV .dropdown-item:hover,#cgclientNAV .dropdown-item:focus-visible{background-color:#00a18514;color:var(--cg-primary-dark)!important}#cgclientNAV a:focus-visible,#cgclientNAV button:focus-visible{outline:2px solid var(--cg-on-primary);outline-offset:2px;border-radius:var(--cg-shape)}#cgclientNAV .navbar-toggler{width:48px;height:48px;color:var(--cg-on-primary);box-shadow:none;transition:background-color var(--cg-dur-short) var(--cg-ease-standard);background-color:#0000;border:0;border-radius:50%;flex:none;place-items:center;padding:0;position:relative}#cgclientNAV .navbar-toggler:hover,#cgclientNAV .navbar-toggler:focus-visible{background-color:var(--cg-state-hover)}#cgclientNAV .navbar-toggler:active{background-color:var(--cg-state-press)}#cgclientNAV.cg-nav-open .navbar-toggler .navbar-toggler-icon{background-image:none}#cgclientNAV.cg-nav-open .navbar-toggler:before,#cgclientNAV.cg-nav-open .navbar-toggler:after{content:\"\";width:18px;height:2px;transition:transform var(--cg-dur-medium) var(--cg-ease-standard);background:currentColor;border-radius:2px;position:absolute}#cgclientNAV.cg-nav-open .navbar-toggler:before{transform:rotate(45deg)}#cgclientNAV.cg-nav-open .navbar-toggler:after{transform:rotate(-45deg)}@media (width>=1200px){#cgclientNAV .navbar-toggler{display:none!important}}@media (width<=1199.98px){#cgclientNAV{flex-wrap:nowrap;align-items:center;padding:0 8px!important}#cgclientNAV>div{flex:auto;align-items:center;min-width:0;height:auto!important;display:flex!important}#cgclientNAV .navbar-toggler{margin-left:8px;display:grid}#cgclientNAV .teacherlist{display:none!important}#cgclientNAV #navbarSimple:not([hidden]){overscroll-behavior:contain;z-index:1100;max-height:calc(100vh - 80px);animation:cg-menu-in var(--cg-dur-medium) var(--cg-ease-decel) both;top:calc(100% + 8px);left:8px;right:8px;overflow:hidden auto;background:var(--cg-surface)!important;border-radius:var(--cg-shape)!important;width:auto!important;height:auto!important;box-shadow:var(--cg-elev-8)!important;border:0!important;margin:0!important;padding:8px!important;display:block!important;position:absolute!important}@keyframes cg-menu-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}#cgclientNAV .navbar-nav{flex-direction:column!important;align-items:stretch!important;width:100%!important;height:auto!important;padding:0!important;display:flex!important}#cgclientNAV .navbar-nav .nav-item{width:100%!important;height:auto!important;padding:0!important}#cgclientNAV .navbar-nav .nav-link{width:100%;color:var(--cg-text);justify-content:flex-start;padding:0 16px}#cgclientNAV .navbar-nav .nav-link:hover,#cgclientNAV .navbar-nav .nav-link:focus-visible{background-color:#00a18514}#cgclientNAV .navbar-nav .nav-link:active{background-color:#00a18529}#cgclientNAV .navbar-nav .nav-item.current{border-radius:var(--cg-shape);background:var(--cg-state-selected)}#cgclientNAV .navbar-nav .nav-item.current:after{background:var(--cg-primary);border-radius:0 2px 2px 0;width:2px;height:auto;inset:8px auto 8px 0}#cgclientNAV .navbar-nav .nav-item.current>.nav-link{color:var(--cg-primary-dark)}#cgclientNAV #navbarSimple .dropdown,#cgclientNAV #navbarSimple .dropdown-submenu{width:100%!important;min-width:0!important;display:block!important}#cgclientNAV #navbarSimple .dropdown-toggle{justify-content:flex-start}#cgclientNAV #navbarSimple .dropdown-toggle:after{margin-left:auto}#cgclientNAV #navbarSimple .dropdown-menu{float:none;border-radius:var(--cg-shape);margin:0 0 4px;padding:4px 0;width:100%!important;min-width:0!important;box-shadow:none!important;background:#f4f8f7!important;position:static!important;inset:auto!important;transform:none!important}#cgclientNAV #navbarSimple .dropdown-menu.show,#cgclientNAV #navbarSimple .dropdown-menu[style*=display]{display:block!important}#cgclientNAV #navbarSimple .dropdown-item{white-space:normal;overflow-wrap:anywhere;min-height:44px;padding:0 16px 0 32px;font-size:13px}#cgclientNAV #navbarSimple .dropdown-item:hover,#cgclientNAV #navbarSimple .dropdown-item:focus-visible{background-color:#00a1851a}}body.cg-pretty-courses{box-sizing:border-box;justify-content:center;align-items:center;min-height:100vh;padding:clamp(.75rem,3vw,2.5rem) .75rem;height:auto!important;display:flex!important}body.cg-pretty-courses .courselist-box{justify-content:center;width:100%;display:flex}body.cg-pretty-courses .cg-course-flow,body.cg-pretty-courses .cg-course-flow #cgcontainerID{max-width:900px;width:100%!important;margin-left:auto!important;margin-right:auto!important}body.cg-pretty-courses .cg-course-flow .courselist{padding:1.25rem}body.cg-pretty-courses .cg-course-flow .courselist-title{color:var(--cg-green-dark)}@media (width<=991.98px){body.cg-pretty-courses{display:block!important}}body.cg-pretty-courses #cgcontainerID .courselist>div{grid-template-columns:repeat(auto-fill,minmax(min(240px,100%),1fr))!important;gap:.75rem!important}body.cg-pretty-courses #cgcontainerID .courselist>div>a{box-sizing:border-box;border-radius:var(--cg-shape);background:var(--cg-surface);box-shadow:var(--cg-elev-1);overflow-wrap:anywhere;transition:border-color var(--cg-dur-short) var(--cg-ease-standard), box-shadow var(--cg-dur-medium) var(--cg-ease-standard);border:1px solid #0000;display:block}body.cg-pretty-courses #cgcontainerID .courselist>div>a:hover,body.cg-pretty-courses #cgcontainerID .courselist>div>a:focus-visible{border-color:var(--cg-green);box-shadow:var(--cg-elev-2);text-decoration:none}body.cg-pretty-courses #cgcontainerID .courselist>div>a>div,body.cg-pretty-courses #cgcontainerID .courselist>div>a>div:hover{box-sizing:border-box;width:100%;height:auto;min-height:48px;box-shadow:none;border:0;border-radius:0;align-items:center;gap:12px;padding:8px 16px;font-size:15px;font-weight:500;display:flex;color:var(--cg-text)!important}body.cg-pretty-courses #cgcontainerID .courselist>div>a>div:after{content:\"\";border-top:2px solid var(--cg-muted);border-right:2px solid var(--cg-muted);flex:none;width:8px;height:8px;margin-left:auto;transform:rotate(45deg)}@media (width<=991.98px){body.cg-pretty-courses #cgcontainerID .courselist>div{grid-template-columns:1fr!important}}.cg-pretty-directory-toggle{display:none}.cg-pretty-directory-toggle:before{content:\"\";width:18px;height:18px;color:var(--cg-green);background-image:linear-gradient(currentColor,currentColor),linear-gradient(currentColor,currentColor),linear-gradient(currentColor,currentColor);background-position:0 0,0 8px,0 16px;background-repeat:no-repeat;background-size:100% 2px;flex:none}@media (width<=991.98px){.cg-pretty-directory-toggle{border-radius:var(--cg-shape);background:var(--cg-surface);width:100%;min-height:52px;box-shadow:var(--cg-elev-1);color:var(--cg-text);font:inherit;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--cg-dur-short) var(--cg-ease-standard), box-shadow var(--cg-dur-medium) var(--cg-ease-standard);border:0;align-items:center;gap:12px;margin:0 0 8px;padding:0 16px;font-size:15px;font-weight:500;display:flex}.cg-pretty-directory-toggle:hover{background-color:#00a1850a}.cg-pretty-directory-toggle:active{background-color:var(--cg-state-hover)}.cg-pretty-directory-toggle.cg-open{box-shadow:var(--cg-elev-2)}.cg-pretty-directory-toggle:after{content:\"\";border-right:2px solid var(--cg-muted);border-bottom:2px solid var(--cg-muted);width:9px;height:9px;transition:transform var(--cg-dur-medium) var(--cg-ease-standard);flex:none;transform:translateY(-2px)rotate(45deg)}.cg-pretty-directory-toggle.cg-open:after{transform:translateY(2px)rotate(-135deg)}.cg-dir-count{background:var(--cg-state-selected);min-width:24px;color:var(--cg-green-dark);text-align:center;border-radius:12px;flex:none;margin-left:auto;padding:2px 8px;font-size:12px;font-weight:600;line-height:16px}.cg-dir-count[hidden]{display:none!important}#cgcontainerID>.row>.col-2.mr-2-box{box-sizing:border-box;background:var(--cg-surface);border-radius:var(--cg-shape);box-shadow:var(--cg-elev-1);overscroll-behavior:contain;flex:none;max-height:60vh;margin:0 0 12px;padding:8px;overflow-y:auto;width:100%!important;max-width:100%!important}#cgcontainerID>.row>.col-2.mr-2-box[hidden]{display:none!important}#cgcontainerID .mr-2-box>.text-muted{letter-spacing:.08em;border-bottom:0;margin:4px 16px 8px;padding:0;font-size:12px;font-weight:500;line-height:16px;display:block;color:var(--cg-muted)!important}#cgcontainerID .mr-2-box>.text-muted strong{font-weight:600}#cgcontainerID .mr-2-box>.text-muted i{color:var(--cg-green);margin-right:4px}#cgcontainerID .mr-2-box .list-group>.list-group-item{box-sizing:border-box;border-radius:var(--cg-shape);overflow-wrap:anywhere;min-height:48px;transition:background-color var(--cg-dur-short) var(--cg-ease-standard);background-color:#0000;border:0;align-items:center;margin-bottom:2px;padding:8px 12px 8px 16px;font-size:14px;line-height:1.4;display:flex;position:relative;color:var(--cg-text)!important}#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-action:hover,#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-action:focus-visible{z-index:auto;background-color:var(--cg-state-hover);text-decoration:none;color:var(--cg-text)!important}#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-action:active{background-color:var(--cg-state-press)}#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-primary,#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-primary.list-group-item-action:hover,#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-primary.list-group-item-action:focus-visible{background-color:var(--cg-state-selected);font-weight:500;color:var(--cg-green-dark)!important}#cgcontainerID .mr-2-box .list-group>.list-group-item.list-group-item-primary:before{content:\"\";background:var(--cg-green);border-radius:0 2px 2px 0;width:2px;position:absolute;top:8px;bottom:8px;left:0}#cgcontainerID>.row{display:block;margin-left:0!important;margin-right:0!important}#cgcontainerID>.row>.col-10{flex:0 0 100%;padding:0;width:100%!important;max-width:100%!important}#cgcontainerID .col-10 table{max-width:100%;display:block;overflow-x:auto}}.cg-copy-unlocked,.cg-copy-unlocked body,.cg-copy-unlocked body *{-webkit-user-select:text!important;user-select:text!important}.cg-copy-unlocked body{-webkit-touch-callout:default!important}@media (prefers-reduced-motion:reduce){#cgclientNAV *,#cgclientNAV :before,#cgclientNAV :after,.cg-pretty-courses *,#cgcontainerID *{transition:none!important;animation:none!important}}"); (() => { const bpNav = window.matchMedia("(max-width: 1199.98px)"); const bpLayout = window.matchMedia("(max-width: 991.98px)"); const watch = (mq, fn) => { mq.addEventListener?.("change", fn); fn(); }; function setupNavbar() { const nav = document.getElementById("cgclientNAV"); const panel = document.getElementById("navbarSimple"); const toggler = nav?.querySelector(".navbar-toggler"); if (!nav || !panel || !toggler) return; toggler.removeAttribute("data-toggle"); toggler.removeAttribute("data-target"); const close = () => { panel.hidden = true; panel.classList.remove("show"); toggler.setAttribute("aria-expanded", "false"); nav.classList.remove("cg-nav-open"); }; const open = () => { panel.hidden = false; panel.classList.add("show"); toggler.setAttribute("aria-expanded", "true"); nav.classList.add("cg-nav-open"); }; toggler.addEventListener("click", (e) => { e.stopImmediatePropagation(); panel.hidden ? open() : close(); }, true); panel.addEventListener("keydown", (e) => { if (e.key === "Escape") { close(); toggler.focus(); } }); watch(bpNav, () => close()); } function setupCourses() { const box = document.querySelector(".courselist-box"); if (!box) return; document.body.classList.add("cg-pretty-courses"); box.classList.add("cg-course-flow"); } function setupAssignments() { const row = document.querySelector("#cgcontainerID > .row"); const sidebar = row?.querySelector(".col-2.mr-2-box"); if (!row || !sidebar) return; if (document.querySelector(".cg-pretty-directory-toggle")) return; const button = document.createElement("button"); button.className = "cg-pretty-directory-toggle"; button.type = "button"; const label = document.createElement("span"); label.className = "cg-dir-label"; label.textContent = "作业目录"; const count = document.createElement("span"); count.className = "cg-dir-count"; const refreshCount = () => { const n = sidebar.querySelectorAll(".list-group-item").length; count.textContent = String(n); count.hidden = n === 0; }; refreshCount(); button.append(label, count); button.setAttribute("aria-expanded", "false"); button.setAttribute("aria-controls", sidebar.id || "cg-pretty-directory"); if (!sidebar.id) sidebar.id = "cg-pretty-directory"; let open = false; const sync = () => { sidebar.hidden = !open && bpLayout.matches; button.hidden = !bpLayout.matches; button.setAttribute("aria-expanded", String(open)); button.classList.toggle("cg-open", open); label.textContent = open ? "收起目录" : "作业目录"; if (open) refreshCount(); }; button.addEventListener("click", () => { open = !open; sync(); }); sidebar.addEventListener("keydown", (e) => { if (e.key === "Escape" && bpLayout.matches) { open = false; sync(); button.focus(); button.scrollIntoView?.({ block: "nearest" }); } }); watch(bpLayout, () => { if (!bpLayout.matches) open = false; sync(); }); row.prepend(button); } function setupCopyUnlock() { if (document.documentElement.dataset.cgCopyUnlocked === "true") return; document.documentElement.dataset.cgCopyUnlocked = "true"; document.documentElement.classList.add("cg-copy-unlocked"); const allow = (event) => { event.stopImmediatePropagation(); }; for (const type of [ "copy", "cut", "contextmenu", "selectstart", "dragstart" ]) { document.addEventListener(type, allow, true); window.addEventListener(type, allow, true); } document.querySelectorAll("[oncopy],[oncut],[oncontextmenu],[onselectstart],[ondragstart]").forEach((el) => { el.removeAttribute("oncopy"); el.removeAttribute("oncut"); el.removeAttribute("oncontextmenu"); el.removeAttribute("onselectstart"); el.removeAttribute("ondragstart"); }); } const run = () => { setupCourses(); setupAssignments(); setupNavbar(); setupCopyUnlock(); }; if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", run, { once: true }); else run(); })(); })();