/* $ SELECTOR */ HTMLElement.prototype.$ = function(selector) { return window.$(selector, this) } DocumentFragment.prototype.$ = function(selector) { return window.$(selector, this) } window.$ = function(selector, el = document) { if(selector[0] === "#" || selector.includes("[name")) { return el.querySelector(selector) } else { let result = el.querySelectorAll(selector); return result.length === 1 ? result[0] : result } } /* CONSOLE */ console.red = function(message) { this.log(`%c${message}`, "color: rgb(254, 79, 42);"); }; console.green = function(message) { this.log(`%c${message}`, "color: rgb(79, 254, 42);"); } /* GET CSS VARIABLES FOR DARK OR LIGHT MODE */ window.darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.classList.add(darkMode ? 'dark' : 'light'); window.getColor = function(name) { const rootStyles = getComputedStyle(document.documentElement); const color = rootStyles.getPropertyValue(`--${name}`).trim(); if(!color) { throw new Error("Color not found") } return color } /* MOBILE */ window.isMobile = function isMobile() { return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(navigator.userAgent); } window.css = function css(cssString) { let container = document.querySelector("style#pageStyle"); if(!container) { container = document.createElement('style'); container.id = "pageStyle"; document.head.appendChild(container); } let primarySelector = cssString.substring(0, cssString.indexOf("{")).trim(); primarySelector = primarySelector.replace(/\*/g, "all"); primarySelector = primarySelector.replace(/#/g, "id-"); primarySelector = primarySelector.replace(/,/g, ""); let stylesheet = container.querySelector(`:scope > style[id='${primarySelector}']`) if(!stylesheet) { stylesheet = document.createElement('style'); stylesheet.id = primarySelector; stylesheet.appendChild(document.createTextNode(cssString)); container.appendChild(stylesheet); } else { stylesheet.innerText = cssString } } window.html = function html(elementString) { let parser = new DOMParser(); let doc = parser.parseFromString(elementString, 'text/html'); return doc.body.firstChild; } window.util = {} window.util.observeClassChange = (el, callback) => { if (!el || !(el instanceof Element)) { throw new Error("observeClassChange requires a valid DOM element."); } const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.type === "attributes" && mutation.attributeName === "class") { callback(el.classList); } } }); observer.observe(el, { attributes: true, attributeFilter: ["class"] }); return observer; // Optional: return it so you can disconnect later }