dnum5emepower / Flatten Zimbra Calendar Background Colors

// ==UserScript==
// @name         Flatten Zimbra Calendar Background Colors
// @version      1.3
// @author       You
// @match        https://partage.unistra.fr/*
// @grant        none
// @license      MIT
// ==/UserScript==

//Observer that checks if the calendar node exists
var calendarObserver = new MutationObserver(function (mutations, observer) {
    console.log("Document mutation detected");

    //If the calendar node exists
    if (document.getElementsByClassName("ZmCalViewMgr").length > 0) {
        console.log("Calendar detected");

        //regex to identify if the correct style is applied afterwards
        var re = /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\) none repeat scroll 0% 0%/;
        //Create an events observer that will change all backgrounds when triggered
        var eventsObserver = new MutationObserver(function (mutations, observer) {
            console.log("Event mutation detected");
            changeBackgroundStyle(eventsObserver, re);
        });

        //Events observer is triggered when background attributes of calendar node or any of its children are modified
        eventsObserver.observe(document.getElementsByClassName("ZmCalViewMgr")[0], {
            subtree: true,
            attributes: true,
            attributesFilter: ['background'],
            childList: true
        });

        //We disconnect the calendar observer since the events observer is now up and running
        calendarObserver.disconnect();
    }
});

//Calendar observer is triggered whenever a change is made in the document
calendarObserver.observe(document, {
    subtree: true,
    attributes: true
});

//Function to change the backgrounds to a flatter, easier to read format
function changeBackgroundStyle(eventsObserver, re) {
    //Start timer
    let start = new Date();

    //Temporarily disconnect the events observer otherwise our background manipulations will trigger an infinite loop (not needed for firefox 66+, how come ?
    eventsObserver.disconnect();

    //Retrieve all events which all seem to have IDs ending with "_tableBody"
    var events = document.querySelectorAll('*[id$="_tableBody"]');

    //For all events
    events.forEach(function (event) {
        //Delete the very small and useless border between the vertical bar and the event box itself
        event.style.border = 0;

        //If the correct style is not applied to the event background
        if (!re.test(event.style.background)) {
            //Retrieve the color of the event
            let eventColor = event.style.background.split("rgb(")[2].split(")")[0];
            //Set the background style to a flat version of that color
            event.style.background = "rgba(" + eventColor + ", 1) repeat scroll 0% 0%";
            //Set the background style of the events for which the previous line didn't work because their apperance is linked to the style of a child node (no idea why)
            event.firstChild.firstChild.style.background = "rgba(" + eventColor + ", 1)";
        }

        //If the correct style is not applied to the state side bar
        if (event.firstChild.firstChild.firstChild.style.background!="" && !re.test(event.firstChild.firstChild.firstChild.style.background)) {
            //Set the background style of the small "state" vertical bar
            let eventStateColor = event.firstChild.firstChild.firstChild.style.background.split("rgb(")[2].split(")")[0];
            event.firstChild.firstChild.firstChild.style.background = "rgba(" + eventStateColor + ", 1) repeat scroll 0% 0%";
        }
    });

    //Reconnect the events observer
    eventsObserver.observe(document.getElementsByClassName("ZmCalViewMgr")[0], {
        subtree: true,
        attributes: true,
        attributesFilter: ['background'],
        childList: true
    });

    //Stop timer
    let time = new Date() - start;
    //Log time it took in ms
    console.log(time + "ms");
}