diff --git a/README.md b/README.md
index 096032f..0b867b1 100644
--- a/README.md
+++ b/README.md
@@ -78,4 +78,30 @@ int main(){
Save and close, then run ``crafter-build build executable && caddy file-server --listen :8080 --root bin/executable``. if you have caddy installed, if not use your favorite static file server instead. Now you can open the browser at ``http://localhost:8080`` and ``Hello World!`` will appear in the browser.
-This sample can also be viewed in the [HelloElement example](https://forgejo.catcrafts.net/Catcrafts/Crafter.CppDOM/src/branch/master/examples)
\ No newline at end of file
+This sample can also be viewed in the [HelloElement example](https://forgejo.catcrafts.net/Catcrafts/Crafter.CppDOM/src/branch/master/examples)
+
+# Fetch Functionality
+
+The library now includes support for making HTTP requests using the `fetch` function:
+
+```cpp
+import Crafter.CppDOM;
+using namespace Crafter::CppDOMBindings;
+
+int main(){
+ // Make a POST request with body data
+ std::string result = Fetch("https://httpbin.org/post", "{\"test\": \"data\"}");
+
+ // Or make a request without body data
+ std::string result = Fetch("https://httpbin.org/get");
+
+ // Handle the response
+ if (!result.empty()) {
+ // Process the response
+ HtmlElementView body("body");
+ body.SetInnerHTML("Response: " + result);
+ }
+}
+```
+
+This feature allows you to make HTTP requests directly from C++ code running in WebAssembly, which can be useful for communicating with APIs or backend services.
\ No newline at end of file
diff --git a/additional/env.js b/additional/env.js
index c5645c5..e1d5b2e 100644
--- a/additional/env.js
+++ b/additional/env.js
@@ -678,6 +678,27 @@ let env = {
removeDragEnterListener: removeDragEnterListener,
addDragLeaveListener: addDragLeaveListener,
removeDragLeaveListener: removeDragLeaveListener,
+ fetch: async function(url, urlLenght, handlerID) {
+ try {
+ const urlStr = decoder.decode(new Int8Array(window.crafter_webbuild_wasi.instance.exports.memory.buffer, url, urlLenght));
+
+ const response = await fetch(urlStr);
+ const result = await response.text();
+
+ console.log(result);
+
+ const ptr = writeStringToWasm(result);
+ console.log(ptr);
+
+ const { ExecuteFetchHandler} = window.crafter_webbuild_wasi.instance.exports;
+ console.log("callback");
+ ExecuteFetchHandler(handlerID, ptr);
+ WasmFree(ptr);
+
+ } catch (error) {
+ return 0;
+ }
+ }
}
window.crafter_webbuild_env = env;
\ No newline at end of file
diff --git a/examples/FetchExample/main.cpp b/examples/FetchExample/main.cpp
new file mode 100644
index 0000000..01dace9
--- /dev/null
+++ b/examples/FetchExample/main.cpp
@@ -0,0 +1,18 @@
+import Crafter.CppDOM;
+import std;
+using namespace Crafter::CppDOMBindings;
+
+int main(){
+ void* body = GetElementById("body");
+ SetInnerHTML(body, "
Fetch Example
Testing HTTP requests...
");
+
+ Fetch("https://httpbin.org/get", [body](std::string result){
+ std::cout << "callback recieved2" << std::endl;
+ if (!result.empty()) {
+ SetInnerHTML(body, "Fetch Example
Response: " + result + "
");
+ } else {
+ SetInnerHTML(body, "Fetch Example
Failed to fetch data
");
+ }
+ FreeJs(body);
+ });
+}
\ No newline at end of file
diff --git a/examples/FetchExample/project.json b/examples/FetchExample/project.json
new file mode 100644
index 0000000..9750e20
--- /dev/null
+++ b/examples/FetchExample/project.json
@@ -0,0 +1,17 @@
+{
+ "name": "main",
+ "configurations": [
+ {
+ "name": "executable",
+ "implementations": ["main"],
+ "target": "wasm32-wasi",
+ "debug" : true,
+ "dependencies": [
+ {
+ "path":"../../project.json",
+ "configuration":"lib-debug"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/examples/FetchExample/run.sh b/examples/FetchExample/run.sh
new file mode 100755
index 0000000..e706621
--- /dev/null
+++ b/examples/FetchExample/run.sh
@@ -0,0 +1 @@
+caddy file-server --listen :8080 --root bin/executable
\ No newline at end of file
diff --git a/interfaces/Crafter.CppDOM-BindingsExport.cppm b/interfaces/Crafter.CppDOM-BindingsExport.cppm
index 02d45f2..d287705 100644
--- a/interfaces/Crafter.CppDOM-BindingsExport.cppm
+++ b/interfaces/Crafter.CppDOM-BindingsExport.cppm
@@ -24,76 +24,79 @@ import :EventTypes;
export namespace Crafter::CppDOMBindings {
std::int32_t clickHandlerMaxId = 0;
- std::unordered_map>* clickHandlers = new std::unordered_map>();
+ std::unordered_map>* clickHandlers = new std::unordered_map>();
std::int32_t mouseOverHandlerMaxId = 0;
- std::unordered_map>* mouseOverHandlers = new std::unordered_map>();
+ std::unordered_map>* mouseOverHandlers = new std::unordered_map>();
std::int32_t mouseOutHandlerMaxId = 0;
- std::unordered_map>* mouseOutHandlers = new std::unordered_map>();
+ std::unordered_map>* mouseOutHandlers = new std::unordered_map>();
std::int32_t mouseMoveHandlerMaxId = 0;
- std::unordered_map>* mouseMoveHandlers = new std::unordered_map>();
+ std::unordered_map>* mouseMoveHandlers = new std::unordered_map>();
std::int32_t mouseDownHandlerMaxId = 0;
- std::unordered_map>* mouseDownHandlers = new std::unordered_map>();
+ std::unordered_map>* mouseDownHandlers = new std::unordered_map>();
std::int32_t mouseUpHandlerMaxId = 0;
- std::unordered_map>* mouseUpHandlers = new std::unordered_map>();
+ std::unordered_map>* mouseUpHandlers = new std::unordered_map>();
std::int32_t focusHandlerMaxId = 0;
- std::unordered_map>* focusHandlers = new std::unordered_map>();
+ std::unordered_map>* focusHandlers = new std::unordered_map>();
std::int32_t blurHandlerMaxId = 0;
- std::unordered_map>* blurHandlers = new std::unordered_map>();
+ std::unordered_map>* blurHandlers = new std::unordered_map>();
std::int32_t keyDownHandlerMaxId = 0;
- std::unordered_map>* keyDownHandlers = new std::unordered_map>();
+ std::unordered_map>* keyDownHandlers = new std::unordered_map>();
std::int32_t keyUpHandlerMaxId = 0;
- std::unordered_map>* keyUpHandlers = new std::unordered_map>();
+ std::unordered_map>* keyUpHandlers = new std::unordered_map>();
std::int32_t keyPressHandlerMaxId = 0;
- std::unordered_map>* keyPressHandlers = new std::unordered_map>();
+ std::unordered_map>* keyPressHandlers = new std::unordered_map>();
std::int32_t changeHandlerMaxId = 0;
- std::unordered_map>* changeHandlers = new std::unordered_map>();
+ std::unordered_map>* changeHandlers = new std::unordered_map>();
std::int32_t submitHandlerMaxId = 0;
- std::unordered_map>* submitHandlers = new std::unordered_map>();
+ std::unordered_map>* submitHandlers = new std::unordered_map>();
std::int32_t inputHandlerMaxId = 0;
- std::unordered_map>* inputHandlers = new std::unordered_map>();
+ std::unordered_map>* inputHandlers = new std::unordered_map>();
std::int32_t resizeHandlerMaxId = 0;
- std::unordered_map>* resizeHandlers = new std::unordered_map>();
+ std::unordered_map>* resizeHandlers = new std::unordered_map>();
std::int32_t scrollHandlerMaxId = 0;
- std::unordered_map>* scrollHandlers = new std::unordered_map>();
+ std::unordered_map>* scrollHandlers = new std::unordered_map>();
std::int32_t contextMenuHandlerMaxId = 0;
- std::unordered_map>* contextMenuHandlers = new std::unordered_map>();
+ std::unordered_map>* contextMenuHandlers = new std::unordered_map>();
std::int32_t dragStartHandlerMaxId = 0;
- std::unordered_map>* dragStartHandlers = new std::unordered_map>();
+ std::unordered_map>* dragStartHandlers = new std::unordered_map>();
std::int32_t dragEndHandlerMaxId = 0;
- std::unordered_map>* dragEndHandlers = new std::unordered_map>();
+ std::unordered_map>* dragEndHandlers = new std::unordered_map>();
std::int32_t dropHandlerMaxId = 0;
- std::unordered_map>* dropHandlers = new std::unordered_map>();
+ std::unordered_map>* dropHandlers = new std::unordered_map>();
std::int32_t wheelHandlerMaxId = 0;
- std::unordered_map>* wheelHandlers = new std::unordered_map>();
+ std::unordered_map>* wheelHandlers = new std::unordered_map>();
std::int32_t dragOverHandlerMaxId = 0;
- std::unordered_map>* dragOverHandlers = new std::unordered_map>();
+ std::unordered_map>* dragOverHandlers = new std::unordered_map>();
std::int32_t dragEnterHandlerMaxId = 0;
- std::unordered_map>* dragEnterHandlers = new std::unordered_map>();
+ std::unordered_map>* dragEnterHandlers = new std::unordered_map>();
std::int32_t dragLeaveHandlerMaxId = 0;
- std::unordered_map>* dragLeaveHandlers = new std::unordered_map>();
+ std::unordered_map>* dragLeaveHandlers = new std::unordered_map>();
+
+ std::int32_t fetchHandlerMaxId = 0;
+ std::unordered_map>* fetchHandlers = new std::unordered_map>();
}
extern "C" {
@@ -204,30 +207,19 @@ extern "C" {
__attribute__((export_name("ExecuteDragLeaveHandler"))) void ExecuteDragLeaveHandler(std::int32_t handlerID, double clientX, double clientY, double screenX, double screenY, std::int32_t button, std::int32_t buttons, bool altKey, bool ctrlKey, bool shiftKey, bool metaKey) {
Crafter::CppDOMBindings::dragLeaveHandlers->find(handlerID)->second(Crafter::MouseEvent(clientX, clientY, screenX, screenY, button, buttons, altKey, ctrlKey, shiftKey, metaKey));
}
-
- // Style functions
- __attribute__((export_name("setStyle"))) void SetStyle(void* ptr, const char* style, std::size_t styleLength) {
- // This will be implemented in JavaScript
+
+ __attribute__((export_name("ExecuteFetchHandler"))) void ExecuteFetchHandler(std::int32_t handlerID, const char* response) {
+ std::cout << handlerID << std::endl;
+ Crafter::CppDOMBindings::fetchHandlers->find(handlerID)->second(response);
+ Crafter::CppDOMBindings::fetchHandlers->erase(handlerID);
}
-
- __attribute__((export_name("setProperty"))) void SetProperty(void* ptr, const char* property, std::size_t propertyLength, const char* value, std::size_t valueLength) {
- // This will be implemented in JavaScript
- }
-
- __attribute__((export_name("addClass"))) void AddClass(void* ptr, const char* className, std::size_t classNameLength) {
- // This will be implemented in JavaScript
- }
-
- __attribute__((export_name("removeClass"))) void RemoveClass(void* ptr, const char* className, std::size_t classNameLength) {
- // This will be implemented in JavaScript
- }
-
- __attribute__((export_name("toggleClass"))) void ToggleClass(void* ptr, const char* className, std::size_t classNameLength) {
- // This will be implemented in JavaScript
- }
-
- __attribute__((export_name("hasClass"))) bool HasClass(void* ptr, const char* className, std::size_t classNameLength) {
- // This will be implemented in JavaScript
- return false;
+}
+
+export namespace Crafter::CppDOMBindings {
+ __attribute__((import_module("env"), import_name("fetch"))) void Fetch(const char* url, std::int32_t urlLenght, std::int32_t handlerID);
+ void Fetch(const std::string_view url, std::function callback) {
+ std::int32_t id = fetchHandlerMaxId++;
+ CppDOMBindings::fetchHandlers->insert({id, callback});
+ Fetch(url.data(), url.size(), id);
}
}
\ No newline at end of file
diff --git a/interfaces/Crafter.CppDOM-BindingsImport.cppm b/interfaces/Crafter.CppDOM-BindingsImport.cppm
index 07d5efb..23ee974 100644
--- a/interfaces/Crafter.CppDOM-BindingsImport.cppm
+++ b/interfaces/Crafter.CppDOM-BindingsImport.cppm
@@ -24,11 +24,11 @@ import :EventTypes;
export namespace Crafter::CppDOMBindings {
__attribute__((import_module("env"), import_name("freeJs"))) void FreeJs(void* ptr);
- __attribute__((import_module("env"), import_name("getElementById"))) void* GetElementById(const char* id, std::size_t idLenght);
+ __attribute__((import_module("env"), import_name("getElementById"))) void* GetElementById(const char* id, std::int32_t idLenght);
void* GetElementById(const std::string_view id) {
return GetElementById(id.data(), id.size());
}
- __attribute__((import_module("env"), import_name("setInnerHTML"))) void SetInnerHTML(void* ptr, const char* html, std::size_t htmlLenght);
+ __attribute__((import_module("env"), import_name("setInnerHTML"))) void SetInnerHTML(void* ptr, const char* html, std::int32_t htmlLenght);
void SetInnerHTML(void* ptr, const std::string_view html) {
SetInnerHTML(ptr, html.data(), html.size());
}
@@ -107,32 +107,32 @@ export namespace Crafter::CppDOMBindings {
__attribute__((import_module("env"), import_name("removeDragLeaveListener"))) void RemoveDragLeaveListener(void* ptr, int id);
// Style functions
- __attribute__((import_module("env"), import_name("setStyle"))) void SetStyle(void* ptr, const char* style, std::size_t styleLength);
+ __attribute__((import_module("env"), import_name("setStyle"))) void SetStyle(void* ptr, const char* style, std::int32_t styleLength);
void SetStyle(void* ptr, const std::string_view style) {
SetStyle(ptr, style.data(), style.size());
}
- __attribute__((import_module("env"), import_name("setProperty"))) void SetProperty(void* ptr, const char* property, std::size_t propertyLength, const char* value, std::size_t valueLength);
+ __attribute__((import_module("env"), import_name("setProperty"))) void SetProperty(void* ptr, const char* property, std::int32_t propertyLength, const char* value, std::int32_t valueLength);
void SetProperty(void* ptr, const std::string_view property, const std::string_view value) {
SetProperty(ptr, property.data(), property.size(), value.data(), value.size());
}
- __attribute__((import_module("env"), import_name("addClass"))) void AddClass(void* ptr, const char* className, std::size_t classNameLength);
+ __attribute__((import_module("env"), import_name("addClass"))) void AddClass(void* ptr, const char* className, std::int32_t classNameLength);
void AddClass(void* ptr, const std::string_view className) {
AddClass(ptr, className.data(), className.size());
}
- __attribute__((import_module("env"), import_name("removeClass"))) void RemoveClass(void* ptr, const char* className, std::size_t classNameLength);
+ __attribute__((import_module("env"), import_name("removeClass"))) void RemoveClass(void* ptr, const char* className, std::int32_t classNameLength);
void RemoveClass(void* ptr, const std::string_view className) {
RemoveClass(ptr, className.data(), className.size());
}
- __attribute__((import_module("env"), import_name("toggleClass"))) void ToggleClass(void* ptr, const char* className, std::size_t classNameLength);
+ __attribute__((import_module("env"), import_name("toggleClass"))) void ToggleClass(void* ptr, const char* className, std::int32_t classNameLength);
void ToggleClass(void* ptr, const std::string_view className) {
ToggleClass(ptr, className.data(), className.size());
}
- __attribute__((import_module("env"), import_name("hasClass"))) bool HasClass(void* ptr, const char* className, std::size_t classNameLength);
+ __attribute__((import_module("env"), import_name("hasClass"))) bool HasClass(void* ptr, const char* className, std::int32_t classNameLength);
bool HasClass(void* ptr, const std::string_view className) {
return HasClass(ptr, className.data(), className.size());
}