// ==UserScript== // @name Compass QoL Enhancer // @namespace blankie-scripts // @match http*://*.compass.education/* // @version 1.10.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 qolTabOpened = false; // we make a copy of window.location.hash because the dashboard tab on a user's page would set the fragment to #dsh for some reason let hashCopy = window.location.hash; // needed because .toString() adds a trailing = for empty values function serializeURLSearchParams(query) { let out = ""; for (let [key, value] of query) { if (out) { out += "&"; } // required for session/... or activity/... out += encodeURIComponent(key).replaceAll("%2F", "/"); if (value) { out += `=${encodeURIComponent(value)}`; } } return out; } function getPanelItemHash(panelId, isDefault) { if (window.location.pathname === "/Organise/Activities/Activity.aspx") { let query = new URLSearchParams(window.location.hash.substring(1)); if (panelId === "learningtasks") { query.delete("qol_open_tab"); query.set("openLearningTaskTab", ""); } else if (isDefault) { query.delete("qol_open_tab"); query.delete("openLearningTaskTab"); } else { query.set("qol_open_tab", panelId); query.delete("openLearningTaskTab"); } return `#${serializeURLSearchParams(query)}`; } return `#${encodeURIComponent(panelId)}`; } function updateInstanceButton(instanceDetails, instanceButton, offset) { // Make previous/next session buttons links let index = instanceDetails.instanceStore.indexOfId(instanceDetails.m_instanceId); index += offset; if (index >= 0 && index < instanceDetails.instanceStore.count()) { let url = `#session/${instanceDetails.instanceStore.getAt(index).internalId}`; instanceButton.el.dom.href = url; } else { instanceButton.el.dom.removeAttribute("href"); } } function handleInstanceButtonClick(event) { if (event.ctrlKey) { event.stopImmediatePropagation(); } } function handleActivityManager(element) { let instanceDetails = unsafeWindow.Ext.getCmp(element.id).m_InstanceDetailsWidget; let instanceNavigatorToolbar = instanceDetails.getInstanceNavigatorToolbar(); let previousInstanceButton = instanceNavigatorToolbar.getComponent("previousInstanceButton"); let nextInstanceButton = instanceNavigatorToolbar.getComponent("nextInstanceButton"); let comboSelectInstance = instanceDetails.getCmbSelectIntance(); // not a typo :) let realUpdateInstanceHeader = instanceDetails.updateInstanceHeader; instanceDetails.updateInstanceHeader = function() { realUpdateInstanceHeader.apply(this, arguments); updateInstanceButton(instanceDetails, previousInstanceButton, -1); updateInstanceButton(instanceDetails, nextInstanceButton, 1); }; for (let button of [previousInstanceButton, nextInstanceButton]) { button.el.dom.addEventListener("click", handleInstanceButtonClick, {passive: true}); // move all previous handlers back to the front // new relic's browser agent would've borked this, but it did not?? // i'll take what i can get i guess // (note to self: unsafeWindow.NREUM = true if this breaks) for (let handler of unsafeWindow.Ext.EventManager.getEventListenerCache(button, "click")) { button.el.dom.removeEventListener("click", handler.wrap); button.el.dom.addEventListener("click", handler.wrap); } } comboSelectInstance.tpl.html = comboSelectInstance.tpl.html.replace("
= maskZIndex && maskMsg.style.display !== "none") { return; } } let closeButton = document.querySelector(".x-window-closable.x-window-active .x-tool-close"); if (closeButton) { closeButton.click(); } } else if (event.target.classList.contains("x-form-file-btn")) { // Make Link Hints work with uploading files event.target.querySelector("input[type=file]").click(); } }, {passive: true}); let style = document.createElement("style"); style.textContent = ` /* Make strikethroughs more noticeable on calendar events and their tooltips */ .ext-cal-evt s, .calendar-tip .title s { text-decoration-thickness: .25em; } `; document.head.append(style); // 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 // unsafeWindow.CKEDITOR may not be set if you're on the login page, for example if (unsafeWindow.CKEDITOR) { let originalOn = unsafeWindow.CKEDITOR.dom.domObject.prototype.on; unsafeWindow.CKEDITOR.dom.domObject.prototype.on = function(type, listener) { // https://stackoverflow.com/a/10815581 if (type !== "contextmenu") { return originalOn.apply(this, arguments); } }; } // Uncheck the Remember Me button by default if (window.location.pathname === "/login.aspx") { document.querySelector("#rememberMeChk").checked = false; }