MyrddinE / Herzing ID Highlight

// ==UserScript==
// @name         Herzing ID Highlight
// @namespace    https://openuserjs.org/users/MyrddinE
// @version      0.71
// @description  Clarify Herzing course IDs with educational coloration. Only useful to Herzing staff.
// @author       Myrddin Emrys
// @copyright    2019, Myrddin Emrys (https://openuserjs.org/users/MyrddinE)
// @match        https://herzing.instructure.com/accounts/*
// @match        https://herzing.instructure.com/users/*
// @match        https://herzing.beta.instructure.com/accounts/*
// @match        https://herzing.test.instructure.com/accounts/*
// @grant        GM_addStyle
// @run-at       document-idle
// @license      AGPL-3.0-or-later
// @updateURL    https://openuserjs.org/meta/MyrddinE/Herzing_ID_Highlight.meta.js
// @downloadURL  https://openuserjs.org/install/MyrddinE/Herzing_ID_Highlight.user.js
// ==/UserScript==

(function() {
    'use strict';

    var delayTimerId;

    GM_addStyle(`
div.courses ul.context_list {
  max-height: 50em !important
}
    `);

    const getSemester = (semesterNum) => {
        switch(semesterNum) {
            case '1': return 'Spring';
            case '2': return 'Summer';
            case '3': return 'Fall';
            default: return 'Error';
        }
    }

    const getTerm = (termCode) => {
        switch(termCode) {
            case 'A14': return '4 weeks, first half of A term.';
            case 'A54': return '4 weeks, last half of A term.';
            case 'B14': return '4 weeks, first half of B term.';
            case 'B54': return '4 weeks, last half of B term.';
            case 'A18': return '8 weeks, first half of semester.';
            case 'B18': return '8 weeks, last half of semester.';
            case 'C16': return '16 weeks, full semester.';
            case 'H1': return '6 weeks, first HOA term.';
            case 'H2': return '6 weeks, second HOA term.';
            case 'H3': return '6 weeks, third HOA term.';
            default: return 'Unknown term';
        }
    }

    const colorCourseIDs = () => {
        var input = document.querySelector('input[placeholder="Search people..."][value=""]');
        if (input) {input.focus();}
        input = document.querySelector('input[placeholder="Search courses..."][value=""]');
        if (input) {input.focus();}


        var els = document.getElementsByTagName("td");
        for (var i = 0, l = els.length; i < l; i++) {
            var el = els[i];
            if (/^(AKR|ATL|BHM|BRK|KEN|MPL|MSN|NOR|ONL|ORL)-([0-9ABCZH]+)-([A-Z0-9]+)-([A-Z0-9]+)$/.test(el.innerHTML)) {
                el.setAttribute("style","white-space: nowrap;");
                el.innerHTML = el.innerHTML.replace(
                    /^(AKR|ATL|BHM|BRK|KEN|MPL|MSN|NOR|ONL|ORL)-([0-9ABCZH]+)-([A-Z0-9]+)-([A-Z0-9]+)$/g,
                    `<span title='Campus Code' style='background-color:#FFB'>$1</span>-<span title='Nonstandard Term Code' style='background-color:#EFE'>$2</span>-<span title='Course ID' style='background-color:#DFF'>$3</span>-<span title='Section' style='background-color:#EEF'>$4</span>`
                );
                var reTerm = /\>(Z?)(2)([0-9][0-9])([123])([ABCH])([0-9][0-9]?)\</
                var result = reTerm.exec(el.innerHTML)
                
                if (result) {
                    console.log(`Found ${result[0]} in ${el.innerHTML}`);
                    var newTerm = `<span title='${('Z' === result[1]) ? 'HOA ' : ''}Year Semester Term
${('Z' === result[1]) ? '   ' + result[1] + '   ' : ''} ${result[2]}${result[3]}        ${result[4]}        ${result[5]}${result[6]}
${('Z' === result[1]) ? "\nAtlanta HOA Term: " + result[1] + "\n" : ''}
Year (${result[2]+result[3]}): ${result[2]}0${result[3]}

Semester (${result[4]}): ${getSemester(result[4])}

Term (${result[5]}${result[6]}): ${getTerm(result[5]+result[6])}'>${result.slice(1).join('')}</span>`;
                    el.innerHTML = el.innerHTML.replace(result.slice(1).join(''),newTerm);
                }
            }
        }
    }

    // Color the Course IDs after there are no DOMNodeInserted events for half a second.
    function pushBack () {
        if (delayTimerId) {clearTimeout(delayTimerId)}

        delayTimerId = setTimeout(colorCourseIDs,500);
    }

    document.addEventListener('DOMNodeInserted', pushBack, false);

})();