Last active
August 15, 2024 02:00
-
-
Save Steve-Tech/35462ed4eb2580c8d604f595aee580cf to your computer and use it in GitHub Desktop.
Enhancements to the QUT Canvas, may work on other instances of Canvas by Instructure. Re-sorts the 'Courses' menu by semester & changes the course link to the modules page.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name QUT Canvas++ | |
// @namespace https://stevetech.me/ | |
// @version 0.4.2 | |
// @description Enhancements to the QUT Canvas, may work on other instances of Canvas by Instructure. | |
// @author Steve-Tech | |
// @match https://canvas.qut.edu.au/* | |
// @icon https://instructure-uploads-apse2.s3.ap-southeast-2.amazonaws.com/account_218620000000000001/attachments/792/favicon.ico | |
// @grant none | |
// @run-at document-idle | |
// @updateURL https://gist.githubusercontent.com/Steve-Tech/35462ed4eb2580c8d604f595aee580cf/raw/QUT%2520Canvas++.js | |
// @downloadURL https://gist.githubusercontent.com/Steve-Tech/35462ed4eb2580c8d604f595aee580cf/raw/QUT%2520Canvas++.js | |
// @supportURL https://gist.github.com/Steve-Tech/35462ed4eb2580c8d604f595aee580cf | |
// ==/UserScript== | |
(function () { | |
'use strict'; | |
function startTrayObserver(targetNode = document.getElementById("nav-tray-portal")) { | |
trayObserver.observe(targetNode, { childList: true, subtree: true }); | |
} | |
// Wait for #nav-tray-portal to load | |
const bodyObserver = new MutationObserver((mutationsList, observer) => { | |
const targetNode = document.getElementById("nav-tray-portal"); | |
if (targetNode != null) { | |
observer.disconnect(); | |
startTrayObserver(targetNode); | |
} | |
}); | |
const trayObserver = new MutationObserver((mutationsList, observer) => { | |
let courses_elem = document.querySelector("div.navigation-tray-container.courses-tray > div.tray-with-space-for-global-nav > div > ul > li > ul") | |
if (courses_elem != null && !["Loading", ""].includes(courses_elem.innerText) && !courses_elem.dataset?.sorted) { | |
// Set flag to reduce looping | |
courses_elem.dataset.sorted = true; | |
// Get all courses | |
let courses = {}; | |
for (const course of courses_elem.children) { | |
const key = course.querySelector("div:last-of-type")?.innerText; | |
if (!(key in courses)) { | |
courses[key] = []; | |
} | |
let new_node = course.cloneNode(true); | |
new_node.firstChild.href += "/modules" // Add "/modules" to the URL | |
courses[key].push(new_node); | |
} | |
// Put newest courses first | |
let keys = Object.keys(courses); | |
keys.sort((a, b) => { | |
let a_match = a.match("^(?:Term: )?([0-9]{4}) SEM-([12])$"); | |
let b_match = b.match("^(?:Term: )?([0-9]{4}) SEM-([12])$"); | |
if (a_match != null && b_match != null) { | |
// Compare year | |
if (a_match[1] != b_match[1]) { | |
return b_match[1] - a_match[1]; | |
} | |
// Compare semester | |
if (a_match[2] != b_match[2]) { | |
return b_match[2] - a_match[2]; | |
} | |
} | |
// Use default sort | |
return 0; | |
}); | |
let new_children = []; | |
for (const key of keys) { | |
new_children.push(...courses[key]); | |
} | |
observer.disconnect(); // Disconnect observer to reduce looping when mutating children | |
courses_elem.replaceChildren(...new_children); | |
startTrayObserver(); | |
} | |
}); | |
bodyObserver.observe(document.body, { childList: true }); | |
// Use the whole screen when there's an iframe tool | |
if (document.querySelector("iframe.tool_launch")) { | |
document.querySelector("body:not(.full-width):not(.outcomes):not(.body--login-confirmation) .ic-Layout-wrapper").style.maxWidth = "none"; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment