/** * HTML generation and endpoint methods for MenuUtils. * Handles generating dropdown HTML and serving MenuUtils code to the browser. */ const htmlGeneration = { generateHtml(htmlElement, options, savedValue) { htmlElement.innerHTML = options.length ? `${options .map((opt) => ``) .join("")}` : ""; if (savedValue && options.includes(savedValue)) { htmlElement.value = savedValue; } }, createMenuUtilsEndpoint(RED, nodeName, customHelpers = {}) { RED.httpAdmin.get(`/${nodeName}/resources/menuUtils.js`, function(req, res) { console.log(`Serving menuUtils.js for ${nodeName} node`); res.set('Content-Type', 'application/javascript'); const browserCode = this.generateMenuUtilsCode(nodeName, customHelpers); res.send(browserCode); }.bind(this)); }, generateMenuUtilsCode(nodeName, customHelpers = {}) { const defaultHelpers = { validateRequired: `function(value) { return value && value.toString().trim() !== ''; }`, formatDisplayValue: `function(value, unit) { return \`\${value} \${unit || ''}\`.trim(); }` }; const allHelpers = { ...defaultHelpers, ...customHelpers }; const helpersCode = Object.entries(allHelpers) .map(([name, func]) => ` ${name}: ${func}`) .join(',\n'); const classCode = this.constructor.toString(); // <-- this gives full class MenuUtils {...} return ` // Create EVOLV namespace structure window.EVOLV = window.EVOLV || {}; window.EVOLV.nodes = window.EVOLV.nodes || {}; window.EVOLV.nodes.${nodeName} = window.EVOLV.nodes.${nodeName} || {}; // Inject MenuUtils class ${classCode} // Expose MenuUtils instance to namespace window.EVOLV.nodes.${nodeName}.utils = { menuUtils: new MenuUtils(), helpers: { ${helpersCode} } }; // Optionally expose globally window.MenuUtils = MenuUtils; console.log('${nodeName} utilities loaded in namespace'); `; }, }; module.exports = htmlGeneration;