Inventory color display

Implement color BG for inventory stuff

// ==UserScript==
// @name         Inventory color display
// @namespace    http://tampermonkey.net/
// @version      0.2.0
// @description  Implement color BG for inventory stuff
// @author       Ophelia D
// @match        https://mmolb.com/manage-team/inventory
// @icon         https://www.google.com/s2/favicons?sz=64&domain=mmolb.com
// @grant        none
// @license      GNU AGPLv3
// ==/UserScript==

(function() {
    'use strict';

    function waitUntilElementIsRendered(elementOrSelector, timeout) {
        timeout = typeof timeout === "number" ? timeout : 10000;

        const waitForElement = (resolve) => {
            const startTime = window.performance.now();

            const checkElement = () => {
                if (window.performance.now() - startTime >= timeout) {
                    resolve(null); return;
                }

                const element = typeof elementOrSelector === "string" ? document.querySelector(elementOrSelector) : elementOrSelector;
                if (element.innerHTML) {
                    resolve(element); return;
                }

                window.requestAnimationFrame(checkElement);
            };
            window.requestAnimationFrame(checkElement);
        };

        return new Promise(waitForElement);
    }

    function removeStyles(el) {
        el.removeAttribute('style');

        if(el.childNodes.length > 0) {
            for(let child in el.childNodes) {
                /* filter element nodes only */
                if(el.childNodes[child].nodeType == 1) {
                    removeStyles(el.childNodes[child]);
                }
            }
        }
    }

    function processChildrenNode(children) {
        let stat_childrens = children.getElementsByClassName("text-yellow-400");
        if(stat_childrens.length == 0) {
            stat_childrens = children.getElementsByClassName("text-blue-400");
        }
        let count = 0;
        for(let stat_children of stat_childrens) {
            let number = stat_children.getElementsByClassName("font-semibold")[0].innerText.slice(1, -1);
            let type = stat_children.getElementsByClassName("opacity-80")[0].innerText;
            count+=(number-5);
        }
        const efficient=count/(stat_childrens.length*15);
        children.style.backgroundColor=getColorByPerc(efficient*100);
    }

    function refreshBackgroundColor() {
        const grid = document.querySelector("div.grid");
        for(let children of grid.children) {
            removeStyles(children);
            processChildrenNode(children);
        }
        const player_inventories = document.querySelector("div.mt-4").getElementsByClassName("relative group");
        for(let player_object of player_inventories) {
            removeStyles(player_object);
            processChildrenNode(player_object);
        }
    }

    function runAfterDom() {
        const grid = document.querySelector("div.grid");
        const inventory = document.querySelector("div.mt-4");

        const observer = new MutationObserver((mutations) => {
            console.log(mutations);
            refreshBackgroundColor();
        });

        observer.observe(grid, {
            childList: true,
            subtree: true
        });

        observer.observe(inventory, {
            childList: true,
            subtree: true
        });
    }

    function getColorByPerc(perc) {
        let r, g, b = 0;
        const value = Math.round(255 * 0.35);
        if(perc < 50) {
            r = value;
            g = Math.round(value*0.02 * perc);
        }
        else {
            g = value;
            r = Math.round((value*2) - (value*0.02*perc));
        }
        const h = r * 0x10000 + g * 0x100 + b * 0x1;
        return '#' + ('000000' + h.toString(16)).slice(-6);
    }

    waitUntilElementIsRendered("main").then(runAfterDom);
})();