schoolbox web extension :)
1import { getCurrentPeriod } from "@/utils/periodUtils"; 2import { definePlugin } from "@/utils/plugin"; 3 4export default function init() { 5 definePlugin( 6 "subheader", 7 (settings) => { 8 const style = document.createElement("style"); 9 style.classList = "schooltape"; 10 style.innerHTML = ` 11 .subheader span:not(:last-child):not(.period:empty)::after { 12 content: " | "; 13 font-weight: bold; 14 } 15 .subheader a { 16 color: inherit; 17 } 18 `; 19 20 document.head.appendChild(style); 21 22 if (window.location.pathname === "/" && document.getElementsByClassName("timetable")[0]) { 23 createSubheader(); 24 setInterval(updatePeriodSpan, 5000); 25 setInterval(updateClockSpan, 1000); 26 setInterval(updateDateSpan, 60000); 27 } 28 29 function createSubheader() { 30 const subheader = document.querySelector("h2.subheader"); 31 if (!subheader) return; 32 // TODO: Refactor to support hot reload/uninjection 33 // delete all children of the subheader 34 while (subheader.firstChild) { 35 subheader.removeChild(subheader.firstChild); 36 } 37 const span = document.createElement("span"); 38 span.classList.add("schooltape"); 39 subheader.appendChild(span); 40 41 updatePeriodSpan(); 42 updateClockSpan(); 43 updateDateSpan(); 44 } 45 46 async function updatePeriodSpan() { 47 let periodSpan = document.querySelector(".subheader .period"); 48 if (!periodSpan) { 49 const subheader = document.querySelector(".subheader .schooltape"); 50 if (!subheader) return; 51 periodSpan = document.createElement("span"); 52 periodSpan.classList.add("period"); 53 subheader.appendChild(periodSpan); 54 } 55 periodSpan.textContent = ""; 56 57 const period = getCurrentPeriod(); 58 if (period) { 59 const name = period.data.name || period.header.name; 60 const room = period.data.room ? ` (${period.data.room})` : ""; 61 let periodLink = periodSpan.querySelector("a"); 62 if (period.data.name && period.data.link) { 63 // if there's period data 64 if (!periodLink) { 65 periodLink = document.createElement("a"); 66 67 periodLink.target = settings?.toggle.openInNewTab ? "_blank" : "_self"; 68 periodSpan.appendChild(periodLink); 69 } 70 periodLink.href = period.data.link; 71 periodLink.textContent = `${name}${room}`; 72 } else { 73 // if there's only the header 74 periodSpan.textContent = `${name}${room}`; 75 if (periodLink) { 76 periodSpan.removeChild(periodLink); 77 } 78 } 79 } 80 } 81 82 function updateClockSpan() { 83 let clockSpan = document.querySelector(".subheader .clock"); 84 if (!clockSpan) { 85 const subheader = document.querySelector(".subheader .schooltape"); 86 if (!subheader) return; 87 clockSpan = document.createElement("span"); 88 clockSpan.classList.add("clock"); 89 subheader.appendChild(clockSpan); 90 } 91 const date = new Date(); 92 clockSpan.textContent = date.toLocaleTimeString([], { 93 hour: "2-digit", 94 minute: "2-digit", 95 }); 96 } 97 98 function updateDateSpan() { 99 let dateSpan = document.querySelector(".subheader .date"); 100 if (!dateSpan) { 101 const subheader = document.querySelector(".subheader .schooltape"); 102 if (!subheader) return; 103 dateSpan = document.createElement("span"); 104 dateSpan.classList.add("date"); 105 subheader.appendChild(dateSpan); 106 } 107 const date = new Date(); 108 dateSpan.textContent = date.toDateString(); 109 } 110 }, 111 [".subheader"], 112 ); 113}