From eeb4973a2efccc8d6b9579876a21544b2deeaf63 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 19 Dec 2025 00:51:39 +0100 Subject: [PATCH] support common.js (future support for VideoLab tool) --- tools/cdata.js | 2 - wled00/data/common.js | 210 +++++++++++++++++++++++++++++++++++++++++ wled00/wled_server.cpp | 6 ++ 3 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 wled00/data/common.js diff --git a/tools/cdata.js b/tools/cdata.js index be739978..9d77934f 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -304,14 +304,12 @@ writeChunks( str .replace("%%", "%") }, - /* { file: "common.js", name: "JS_common", method: "gzip", filter: "js-minify", }, - */ { file: "settings.htm", name: "PAGE_settings", diff --git a/wled00/data/common.js b/wled00/data/common.js new file mode 100644 index 00000000..d2d69179 --- /dev/null +++ b/wled00/data/common.js @@ -0,0 +1,210 @@ +var d=document; +var loc = false, locip, locproto = "http:"; + +function H(pg="") { window.open("https://mm.kno.wled.ge/"+pg); } +function GH() { window.open("https://github.com/MoonModules/WLED-MM"); } +function gId(c) { return d.getElementById(c); } // getElementById +function cE(e) { return d.createElement(e); } // createElement +function gEBCN(c) { return d.getElementsByClassName(c); } // getElementsByClassName +function gN(s) { return d.getElementsByName(s)[0]; } // getElementsByName +function isE(o) { return Object.keys(o).length === 0; } // isEmpty +function isO(i) { return (i && typeof i === 'object' && !Array.isArray(i)); } // isObject +function isN(n) { return !isNaN(parseFloat(n)) && isFinite(n); } // isNumber +// https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer +function isF(n) { return n === +n && n !== (n|0); } // isFloat +function isI(n) { return n === +n && n === (n|0); } // isInteger +function toggle(el) { gId(el).classList.toggle("hide"); let n = gId('No'+el); if (n) n.classList.toggle("hide"); } +function tooltip(cont=null) { + d.querySelectorAll((cont?cont+" ":"")+"[title]").forEach((element)=>{ + element.addEventListener("pointerover", ()=>{ + // save title + element.setAttribute("data-title", element.getAttribute("title")); + const tooltip = d.createElement("span"); + tooltip.className = "tooltip"; + tooltip.textContent = element.getAttribute("title"); + + // prevent default title popup + element.removeAttribute("title"); + + let { top, left, width } = element.getBoundingClientRect(); + + d.body.appendChild(tooltip); + + const { offsetHeight, offsetWidth } = tooltip; + + const offset = element.classList.contains("sliderwrap") ? 4 : 10; + top -= offsetHeight + offset; + left += (width - offsetWidth) / 2; + + tooltip.style.top = top + "px"; + tooltip.style.left = left + "px"; + tooltip.classList.add("visible"); + }); + + element.addEventListener("pointerout", ()=>{ + d.querySelectorAll('.tooltip').forEach((tooltip)=>{ + tooltip.classList.remove("visible"); + d.body.removeChild(tooltip); + }); + // restore title + element.setAttribute("title", element.getAttribute("data-title")); + }); + }); +}; +// sequential loading of external resources (JS or CSS) with retry, calls init() when done +function loadResources(files, init) { + let i = 0; + const loadNext = () => { + if (i >= files.length) { + if (init) { + d.documentElement.style.visibility = 'visible'; // make page visible after all files are loaded if it was hidden (prevent ugly display) + d.readyState === 'complete' ? init() : window.addEventListener('load', init); + } + return; + } + const file = files[i++]; + const isCSS = file.endsWith('.css'); + const el = d.createElement(isCSS ? 'link' : 'script'); + if (isCSS) { + el.rel = 'stylesheet'; + el.href = file; + const st = d.head.querySelector('style'); + if (st) d.head.insertBefore(el, st); // insert before any