JKU ECTS Sum

Sum up all ECTS points from courses and display them on the page

目前為 2025-01-28 提交的版本,檢視 最新版本

// ==UserScript==
// @name         JKU ECTS Sum
// @namespace    http://tampermonkey.net/
// @version      2025-01-28
// @description  Sum up all ECTS points from courses and display them on the page
// @author       geaggAT
// @match        https://my.jku.at/grades*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=my.jku.at
// @grant        none
// ==/UserScript==



(function() {
    'use strict';

    // Function to parse ECTS values and sum them up
    function calculateECTS() {
        const ectsElements = document.querySelectorAll('small[role="cell"].ng-star-inserted');
        let totalECTS = 0;

        ectsElements.forEach(element => {
            const ectsText = element.textContent.trim();
            const ectsMatch = ectsText.match(/(\d+[,.]\d+)\s*\/\s*(\d+[,.]\d+)/);

            if (ectsMatch) {
                const completedECTS = parseFloat(ectsMatch[1].replace(',', '.'));
                totalECTS += completedECTS;
            }
        });

        return totalECTS.toFixed(2);
    }

    // Display the total ECTS on the page
    function displayTotalECTS(totalECTS) {
        const existingHeader = document.getElementById('ects-total-header');
        if (existingHeader) {
            existingHeader.textContent = `Total ECTS: ${totalECTS}`;
            return;
        }

        const header = document.createElement('div');
        header.id = 'ects-total-header';
        header.style.position = 'fixed';
        header.style.top = '90px';
        header.style.right = '20px';
        header.style.backgroundColor = '#4caf50';
        header.style.color = 'white';
        header.style.padding = '10px';
        header.style.borderRadius = '8px';
        header.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)';
        header.style.zIndex = '9999';
        header.textContent = `Total ECTS: ${totalECTS}`;

        document.body.appendChild(header);
    }

    // Debounce function to limit how often the observer callback runs
    function debounce(func, wait) {
        let timeout;
        return function(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    // Observe changes in the DOM to detect when ECTS data is loaded
    function observeECTS() {
        const targetNode = document.body;
        const config = { childList: true, subtree: true };

        const observer = new MutationObserver(
            debounce(() => {
                const ectsElements = document.querySelectorAll('small[role="cell"].ng-star-inserted');
                if (ectsElements.length > 0) {
                    const totalECTS = calculateECTS();
                    displayTotalECTS(totalECTS);
                }
            }, 500)
        );

        observer.observe(targetNode, config);
    }

    observeECTS();
})();