diff --git a/include/webui_extensions.h b/include/webui_extensions.h new file mode 100644 index 000000000..b6d3a7ef0 --- /dev/null +++ b/include/webui_extensions.h @@ -0,0 +1,86 @@ +/* + WebUI Library Extras + https://webui.me + https://github.com/webui-dev/webui + Copyright (c) 2020-2025 Hassan Draga. + Licensed under MIT License. + All rights reserved. + Canada. +*/ + +#ifndef _WEBUI_EXTENSIONS_H +#define _WEBUI_EXTENSIONS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This is to help the compiler identify whether to compile the extensions API funtions or not + * - If you are including the webui.c file to your source file directly, + * and wish to use the extensions API functions, + * please include this header file before including webui.c, + * or define this macro manually before including webui.c + * - In other cases, as long as the webui.c file is not included directly, + * you might need to define this macro in your compiler settings + */ +#ifndef WEBUI_EXTENSION_API +#define WEBUI_EXTENSION_API +#endif + +#ifndef WEBUI_EXPORT + #define WEBUI_EXPORT + #warning "WEBUI_EXPORT not defined; Please include webui.h before webui_extensions.h" +#endif + +#include +#include + +/** + * @brief Construct a JavaScript string from a format string, + * then execute it without waiting for the response. All clients. + * + * @param window The window number + * @param fmt The JavaScript format string to be run + * + * @warning This function DOES NOT handle escape characters, proceed with caution. + * For example, when passing string arguments that contain quotes or backslashes, + * it may lead to unexpected behavior + * + * @note This function internally uses vsnprintf + * + * @example webui_run_fmt(myWindow, "alert('Hello %s');", "World"); + */ +WEBUI_EXPORT void webui_run_fmt(size_t window, const char* fmt, ...); + +/** + * @brief Construct a JavaScript string from a format string, + * then execute it and get the response back. Work only in single client mode. + * Make sure your local buffer can hold the response. + * + * @param window The window number + * @param timeout The execution timeout in seconds + * @param buffer The local buffer to hold the response + * @param buffer_length The local buffer size + * @param fmt The JavaScript format string to be run + * + * @return Returns True if there is no execution error + * + * @warning This function DOES NOT handle escape characters, proceed with caution. + * For example, when passing string arguments that contain quotes or backslashes, + * it may lead to unexpected behavior + * + * @note This function internally uses vsnprintf + * + * @example bool err = webui_script_fmt(myWindow, 0, myBuffer, myBufferSize, + * "return %d + %d;", 4, 6); + */ +WEBUI_EXPORT bool webui_script_fmt(size_t window, size_t timeout, + char* buffer, size_t buffer_length, + const char* fmt, ...); + +#ifdef __cplusplus +} +#endif + +#endif /*_WEBUI_EXTENSIONS_H */ \ No newline at end of file diff --git a/src/webui.c b/src/webui.c index 7d166404f..271239410 100644 --- a/src/webui.c +++ b/src/webui.c @@ -847,6 +847,33 @@ void webui_run(size_t window, const char* script) { _webui_send_all(win, 0, WEBUI_CMD_JS_QUICK, script, js_len); } +#ifdef WEBUI_EXTENSION_API +void webui_run_fmt(size_t window, const char* fmt, ...) { + int len; + char* buf; + + // Precalculate actual string length + va_list args; + va_start(args, fmt); + len = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + if (len < 1) return; + + buf = (char*)_webui_malloc(len + 1); + if (buf == NULL) return; + + // Format and execute + va_start(args, fmt); + vsnprintf(buf, len + 1, fmt, args); + va_end(args); + + webui_run(window, buf); + + _webui_free_mem((void*)buf); +} +#endif /* WEBUI_EXTENSION_API */ + void webui_set_close_handler_wv(size_t window, bool(*close_handler)(size_t window)) { // Initialization @@ -1065,6 +1092,39 @@ bool webui_script(size_t window, const char* script, size_t timeout, return webui_script_client(&e, script, timeout, buffer, buffer_length); } +#ifdef WEBUI_EXTENSION_API +bool webui_script_fmt( + size_t window, size_t timeout, + char* buffer, size_t buffer_length, + const char* fmt, ...) { + int len; + char* buf; + bool status; + + // Precalculate actual string length + va_list args; + va_start(args, fmt); + len = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + if (len < 1) return false; + + buf = (char*)_webui_malloc(len + 1); + if (buf == NULL) return false; + + // Format and execute + va_start(args, fmt); + vsnprintf(buf, len + 1, fmt, args); + va_end(args); + + status = webui_script(window, buf, timeout, buffer, buffer_length); + + _webui_free_mem((void*)buf); + + return status; +} +#endif /* WEBUI_EXTENSION_API */ + static uint32_t _webui_generate_random_uint32() { uint32_t timestamp = (uint32_t) time(NULL); // Get the higher 16 bits