diff --git a/Compass QoL Enhancer.user.js b/Compass QoL Enhancer.user.js new file mode 100644 index 0000000..d2194ea --- /dev/null +++ b/Compass QoL Enhancer.user.js @@ -0,0 +1,116 @@ +// ==UserScript== +// @name Compass QoL Enhancer +// @namespace blankie-scripts +// @match http*://*.compass.education/* +// @version 1.0.0 +// @author blankie +// @description A userscript that adds small but useful features for Compass, such as the ability to close windows by clicking on the background +// @inject-into page +// @run-at document-end +// ==/UserScript== + +"use strict"; + +let observer = new MutationObserver(function(mutations) { + for (let mutation of mutations) { + if (mutation.type !== "childList") { + continue; + } + for (let node of mutation.addedNodes) { + handleNewNode(node); + } + } +}); +observer.observe(document.body, {childList: true, subtree: true}); + +function handleNewNode(node) { + if (node.nodeType !== 1) { + return; + } + + if (node.localName === "div" && node.classList.contains("ext-cal-evt")) { + handleNewCalendarEvent(node); + } else if (node.classList.contains("ext-cal-hd-ct")) { + // learning tasks need to be handled seperately for some reason + for (let element of node.querySelectorAll("div.ext-cal-evt")) { + handleNewCalendarEvent(element); + } + } else if (window.location.pathname === "/Organise/Activities/Activity.aspx" && node.classList.contains("activityPage__tabPanel")) { + for (let tab of node.querySelectorAll(".x-tab")) { + tab.addEventListener("click", function() { + handleActivityTabClick(tab); + }, {passive: true}); + } + } +} + +document.body.addEventListener("click", function(event) { + // Add the ability to close windows by clicking on the background + // 0px check to make sure that the mask is masking the entire background and not just a small subsection (e.g. a calendar) + if (event.target.classList.contains("x-mask") && event.target.style.left === "0px") { + document.querySelector(".x-window-closable.x-window-active .x-tool-close").click(); + } +}, {passive: true}); + +function handleNewCalendarEvent(element) { + // Turn each calendar event into a link so that Link Hints can recognize it + let a = document.createElement("a"); + for (let attr of element.attributes) { + a.setAttribute(attr.name, attr.value); + } + // fix learning tasks shrinking for some reason + a.style.display = "block"; + a.replaceChildren(...element.childNodes); + let preventCompassHandler = false; + + if (a.classList.contains("activity-type-1")) { + // Add a link for activities/"standard classes" + // missing targetUserId parameter, shouldn't matter too much if you're a student + let eventId = / calendar-event-(\d+) /.exec(a.className)[1]; + a.href = `/Organise/Activities/Activity.aspx#session/${eventId}`; + preventCompassHandler = true; + } else if (a.classList.contains("activity-type-10")) { + // Add a link for learning tasks + // missing userId parameter, shouldn't matter too much if you're a student + a.href = "/Records/User.aspx#learningTasks"; + preventCompassHandler = true; + } + + // prevent ctrl-clicking from changing the current tab + // it seems like the link thing actually effectively killed the default handler anyway + if (preventCompassHandler) { + a.addEventListener("click", function(event) { + event.stopImmediatePropagation(); + }, {passive: true}); + } + + element.replaceWith(a); +} + +function handleActivityTabClick(element) { + // Automatically add or remove &openLearningTaskTab when a tab is clicked + let matches = /^(#(?:session|activity)\/\d+)(?:&openLearningTaskTab)?$/.exec(window.location.hash); + if (!matches) { + return; + } + + let newHash = matches[1]; + if (element.classList.contains("sel-learning-tasks-tab")) { + newHash += "&openLearningTaskTab"; + } + + if (newHash !== window.location.hash) { + history.pushState("", "", newHash); + } +} + +// Suppress that annoying barebones context menu that only has Copy +// why is it not obvious that you can just hold ctrl or shift to suppress it??? +// i know it's compass' fault but i'm still frustrated +// https://stackoverflow.com/a/10815581 +let originalOn = unsafeWindow.CKEDITOR.dom.domObject.prototype.on; +unsafeWindow.CKEDITOR.dom.domObject.prototype.on = function(type, listener) { + if (type !== "contextmenu") { + return originalOn.apply(this, arguments); + } +}; \ No newline at end of file diff --git a/README.md b/README.md index 0418fee..767c457 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,16 @@ to enable scripts to see emails again, inspired by Hacky script to disable the client-side file limit per tab +## Compass QoL Enhancer + +A userscript that adds small but useful features for Compass. Features include: +- The ability to close windows by clicking on the background +- Calendar events being links (they work with [Link Hints](https://lydell.github.io/LinkHints/) + now! you can also ctrl+click on "standard classes" and learning tasks) +- `&openLearningTaskTab` is automatically added whenever you go to the Learning + Tasks tab and removed whenever you go to another tab +- The context menu that only says "Copy" is now suppressed + ## Elements with ID lister A userscript that adds a "Show elements popup" option to the Monkey Menu which