diff --git a/additional/env.js b/additional/env.js index c6500f8..5732832 100644 --- a/additional/env.js +++ b/additional/env.js @@ -362,6 +362,7 @@ function addSubmitListener(ptr, handlerID) { const handler = function (event) { const { ExecuteSubmitHandler } = window.crafter_webbuild_wasi.instance.exports; + event.preventDefault(); ExecuteSubmitHandler(handlerID); }; diff --git a/examples/AllEventHandling/main.cpp b/examples/AllEventHandling/main.cpp index 5c2baf7..d4ffd8b 100644 --- a/examples/AllEventHandling/main.cpp +++ b/examples/AllEventHandling/main.cpp @@ -1,26 +1,180 @@ import Crafter.CppDOM; -using namespace Crafter::CppDOM; -using namespace Crafter::CppDOMBindings; +using namespace Crafter; import std; +HtmlElementPtr body("body", "
" + "

Enhanced Event Handling Demo

" + "
" + "
" + "

Mouse Events

" + "" + "
" + "
" + "
" + "

Keyboard Events

" + "" + "
" + "
" + "
" + "

Focus Events

" + "" + "
" + "
" + "
" + "

Form Events

" + "
" + "" + "" + "" + "
" + "
" + "
" + "
" + "

Window Events

" + "
" + "
" + "
" + "

Drag & Drop Events

" + "
Drag Me!
" + "
Drop Here
" + "
" + "
" + "
" + "

Wheel Events

" + "
Scroll here
" + "
" + "
" + "
" + "
"); + +HtmlElementPtr mouseButton("mouseButton"); +HtmlElementPtr mouseOutput("mouseOutput"); +HtmlElementPtr keyInput("keyInput"); +HtmlElementPtr keyOutput("keyOutput"); +HtmlElementPtr focusInput("focusInput"); +HtmlElementPtr focusOutput("focusOutput"); +HtmlElementPtr formInput("formInput"); +HtmlElementPtr formSelect("formSelect"); +HtmlElementPtr formElement("formElement"); +HtmlElementPtr formOutput("formOutput"); +HtmlElementPtr windowOutput("windowOutput"); +HtmlElementPtr dragSource("dragSource"); +HtmlElementPtr dropTarget("dropTarget"); +HtmlElementPtr dragOutput("dragOutput"); +HtmlElementPtr wheelContainer("wheelContainer"); +HtmlElementPtr wheelOutput("wheelOutput"); + int main() { - HtmlElementView body("body"); - body.SetInnerHTML("

All Event Handling

"); - - HtmlElementView div("div"); - div.SetInnerHTML("

Click me!

"); - div.SetStyle("padding: 20px; background-color: lightblue; cursor: pointer;"); - - // Add click handler - div.AddClickListener([](Crafter::MouseEvent e) { - std::cout << "Clicked!" << std::endl; + mouseButton.AddClickListener([&](MouseEvent event) { + mouseOutput.SetInnerHTML(std::format("

Click: X={}, Y={}

", event.clientX, event.clientY)); + }); + + mouseButton.AddMouseOverListener([&](MouseEvent event) { + mouseOutput.SetInnerHTML(std::format("

Mouse Over: X={}, Y={}

", event.clientX, event.clientY)); + }); + + mouseButton.AddMouseOutListener([&](MouseEvent event) { + mouseOutput.SetInnerHTML(std::format("

Mouse Out: X={}, Y={}

", event.clientX, event.clientY)); + }); + + mouseButton.AddMouseMoveListener([&](MouseEvent event) { + mouseOutput.SetInnerHTML(std::format("

Mouse Move: X={}, Y={}

", event.clientX, event.clientY)); + }); + + mouseButton.AddMouseDownListener([&](MouseEvent event) { + mouseOutput.SetInnerHTML(std::format("

Mouse Down: Button={}, X={}, Y={}

", event.button, event.clientX, event.clientY)); + }); + + mouseButton.AddMouseUpListener([&](MouseEvent event) { + mouseOutput.SetInnerHTML(std::format("

Mouse Up: Button={}, X={}, Y={}

", event.button, event.clientX, event.clientY)); + }); + + keyInput.AddKeyDownListener([&](KeyboardEvent event) { + std::string keyInfo = std::format("

Key Down: Key='{}', Code={}, Ctrl={}, Shift={}, Alt={}

", + event.key, event.keyCode, event.ctrlKey, event.shiftKey, event.altKey); + keyOutput.SetInnerHTML(keyInfo); + }); + + keyInput.AddKeyUpListener([&](KeyboardEvent event) { + std::string keyInfo = std::format("

Key Up: Key='{}', Code={}, Ctrl={}, Shift={}, Alt={}

", + event.key, event.keyCode, event.ctrlKey, event.shiftKey, event.altKey); + keyOutput.SetInnerHTML(keyInfo); + }); + + keyInput.AddKeyPressListener([&](KeyboardEvent event) { + std::string keyInfo = std::format("

Key Press: Key='{}', Code={}, Ctrl={}, Shift={}, Alt={}

", + event.key, event.keyCode, event.ctrlKey, event.shiftKey, event.altKey); + keyOutput.SetInnerHTML(keyInfo); + }); + + // Focus Events + focusInput.AddFocusListener([&](FocusEvent event) { + focusOutput.SetInnerHTML("

Focus: Element gained focus

"); + }); + + focusInput.AddBlurListener([&](FocusEvent event) { + focusOutput.SetInnerHTML("

Blur: Element lost focus

"); + }); + + // Form Events + formInput.AddInputListener([&](InputEvent event) { + formOutput.SetInnerHTML(std::format("

Input: Value='{}'

", event.data)); + }); + + formInput.AddChangeListener([&](ChangeEvent event) { + formOutput.SetInnerHTML(std::format("

Change: Value='{}'

", event.value)); + }); + + formSelect.AddChangeListener([&](ChangeEvent event) { + formOutput.SetInnerHTML(std::format("

Select Change: Value='{}'

", event.value)); + }); + + formElement.AddSubmitListener([&]() { + formOutput.SetInnerHTML("

Submit: Form submitted successfully!

"); + }); + + body.AddResizeListener([&](ResizeEvent event) { + windowOutput.SetInnerHTML(std::format("

Resize: Width={}, Height={}

", event.width, event.height)); + }); + + body.AddScrollListener([&](ScrollEvent event) { + windowOutput.SetInnerHTML(std::format("

Scroll: X={}, Y={}

", event.scrollX, event.scrollY)); + }); + + body.AddContextMenuListener([&](MouseEvent event) { + windowOutput.SetInnerHTML(std::format("

Context Menu: X={}, Y={}

", event.clientX, event.clientY)); + }); + + dragSource.AddDragStartListener([&](MouseEvent event) { + dragOutput.SetInnerHTML("

Drag Start: Dragging started

"); + }); + + dragSource.AddDragEndListener([&](MouseEvent event) { + dragOutput.SetInnerHTML("

Drag End: Dragging ended

"); + }); + + dropTarget.AddDragOverListener([&](MouseEvent event) { + dragOutput.SetInnerHTML("

Drag Over: Dragging over drop target

"); + }); + + dropTarget.AddDragEnterListener([&](MouseEvent event) { + dragOutput.SetInnerHTML("

Drag Enter: Drag entered drop target

"); + }); + + dropTarget.AddDragLeaveListener([&](MouseEvent event) { + dragOutput.SetInnerHTML("

Drag Leave: Drag left drop target

"); + }); + + dropTarget.AddDropListener([&](MouseEvent event) { + dragOutput.SetInnerHTML("

Drop: Item dropped

"); + }); + + wheelContainer.AddWheelListener([&](WheelEvent event) { + wheelOutput.SetInnerHTML(std::format("

Wheel: DeltaX={}, DeltaY={}, DeltaZ={}

", + event.deltaX, event.deltaY, event.deltaZ)); }); - - body.AddChild(div); - - // Demonstrate new bindings - std::string path = GetPathNameString(); - std::cout << "Current path: " << path << std::endl; - - return 0; } \ No newline at end of file diff --git a/examples/FetchExample/main.cpp b/examples/FetchExample/main.cpp index f2209d4..e0120f3 100644 --- a/examples/FetchExample/main.cpp +++ b/examples/FetchExample/main.cpp @@ -1,17 +1,16 @@ import Crafter.CppDOM; import std; +using namespace Crafter; using namespace Crafter::CppDOMBindings; +HtmlElementPtr body("body", "

Fetch Example

Testing HTTP requests...

"); + int main(){ - void* body = GetElementById("body"); - SetInnerHTML(body, "

Fetch Example

Testing HTTP requests...

"); - - Fetch("https://httpbin.org/get", [body](std::string result){ + Fetch("https://httpbin.org/get", [](std::string result){ if (!result.empty()) { - SetInnerHTML(body, "

Fetch Example

Response: " + result + "

"); + body.SetInnerHTML("

Fetch Example

Response: " + result + "

"); } else { - SetInnerHTML(body, "

Fetch Example

Failed to fetch data

"); + body.SetInnerHTML("

Fetch Example

Failed to fetch data

"); } - FreeJs(body); }); } \ No newline at end of file diff --git a/examples/HelloElement/main.cpp b/examples/HelloElement/main.cpp index 366f298..d755b79 100644 --- a/examples/HelloElement/main.cpp +++ b/examples/HelloElement/main.cpp @@ -2,7 +2,7 @@ import Crafter.CppDOM; using namespace Crafter; int main(){ - HtmlElementView body("body"); + HtmlElementPtr body("body"); body.SetInnerHTML("Hello World!"); - //No need to call FreeJs, this is done in the destructor of HtmlElementView. + //No need to call FreeJs, this is done in the destructor of HtmlElementPtr. } \ No newline at end of file diff --git a/examples/InputValueExample/main.cpp b/examples/InputValueExample/main.cpp index 247199a..dc5aba8 100644 --- a/examples/InputValueExample/main.cpp +++ b/examples/InputValueExample/main.cpp @@ -2,16 +2,15 @@ import Crafter.CppDOM; import std; using namespace Crafter; - -HtmlElement* body = new HtmlElement("body", R"(

Input GetValue() and SetValue() Example



)"); -HtmlElement* button = new HtmlElement("button"); -HtmlElement* output = new HtmlElement("valueOutput"); -HtmlElement* input = new HtmlElement("input"); +HtmlElementPtr body("body", R"(

Input GetValue() and SetValue() Example



)"); +HtmlElementPtr button("button"); +HtmlElementPtr output("valueOutput"); +HtmlElementPtr input("input"); int main(){ - button->AddClickListener([](Crafter::MouseEvent) { - std::string newValue = input->GetValue(); - output->SetInnerHTML(newValue); - input->SetValue(""); + button.AddClickListener([](Crafter::MouseEvent) { + std::string newValue = input.GetValue(); + output.SetInnerHTML(newValue); + input.SetValue(""); }); } \ No newline at end of file diff --git a/examples/InteractiveElement/main.cpp b/examples/InteractiveElement/main.cpp index 9a7691f..c683dcf 100644 --- a/examples/InteractiveElement/main.cpp +++ b/examples/InteractiveElement/main.cpp @@ -2,15 +2,15 @@ import Crafter.CppDOM; import std; using namespace Crafter; -HtmlElementView body("body","

Interactive Element Demo

" +HtmlElementPtr body("body","

Interactive Element Demo

" "" "

Click the button above

"); -HtmlElementView* button = new HtmlElement("myButton"); //prevent destruction +HtmlElementPtr button("myButton"); +HtmlElementPtr output("output"); int main() { - button->AddClickListener([](Crafter::MouseEvent event){ - auto output = HtmlElementView("output"); + button.AddClickListener([](Crafter::MouseEvent event){ output.SetInnerHTML("Button was clicked at (" + std::to_string(event.clientX) + ", " + std::to_string(event.clientY) + ")!"); }); } \ No newline at end of file diff --git a/examples/SPAExample/main.cpp b/examples/SPAExample/main.cpp index cd39dd3..4a2a061 100644 --- a/examples/SPAExample/main.cpp +++ b/examples/SPAExample/main.cpp @@ -3,7 +3,7 @@ import std; using namespace Crafter; using namespace Crafter::CppDOMBindings; -HtmlElementView* body = new HtmlElementView("body", R"( +HtmlElementPtr body("body", R"(
)"); -HtmlElementView* home = new HtmlElementView("home"); -HtmlElementView* about = new HtmlElementView("about"); -HtmlElementView* contact = new HtmlElementView("contact"); -HtmlElementView* content = new HtmlElementView("content"); +HtmlElementPtr home("home"); +HtmlElementPtr about("about"); +HtmlElementPtr contact("contact"); +HtmlElementPtr content("content"); void UpdateContent(const std::string_view page) { if (page == "home") { - content->SetInnerHTML("

Home Page

Welcome to the Home page of our Single Page Application!

This demo shows how to use the new history.pushState and popstate event handling features.

"); + content.SetInnerHTML("

Home Page

Welcome to the Home page of our Single Page Application!

This demo shows how to use the new history.pushState and popstate event handling features.

"); } else if (page == "about") { - content->SetInnerHTML("

About Page

This is the About page.

Notice how the URL changes without reloading the page.

"); + content.SetInnerHTML("

About Page

This is the About page.

Notice how the URL changes without reloading the page.

"); } else if (page == "contact") { - content->SetInnerHTML("

Contact Page

This is the Contact page.

You can navigate back and forth using the browser's back/forward buttons.

"); + content.SetInnerHTML("

Contact Page

This is the Contact page.

You can navigate back and forth using the browser's back/forward buttons.

"); } } int main() { - body->SetStyle("font-family: Arial, sans-serif; margin: 0; padding: 20px;"); + body.SetStyle("font-family: Arial, sans-serif; margin: 0; padding: 20px;"); // Add click handlers for navigation - home->AddClickListener([](Crafter::MouseEvent e) { + home.AddClickListener([](Crafter::MouseEvent e) { PushState("{\"page\": \"home\"}", "Home", "/"); UpdateContent("home"); }); - about->AddClickListener([](Crafter::MouseEvent e) { + about.AddClickListener([](Crafter::MouseEvent e) { PushState("{\"page\": \"about\"}", "About", "/about"); UpdateContent("about"); }); - contact->AddClickListener([](Crafter::MouseEvent e) { + contact.AddClickListener([](Crafter::MouseEvent e) { PushState("{\"page\": \"contact\"}", "Contact", "/contact"); UpdateContent("contact"); }); diff --git a/examples/StyleExample/main.cpp b/examples/StyleExample/main.cpp index 5fa2db2..77e967a 100644 --- a/examples/StyleExample/main.cpp +++ b/examples/StyleExample/main.cpp @@ -2,9 +2,9 @@ import Crafter.CppDOM; using namespace Crafter; int main(){ - HtmlElementView body("body","
"); + HtmlElementPtr body("body","
"); // Create a div element - HtmlElementView div("myDiv"); + HtmlElementPtr div("myDiv"); // Set some initial content div.SetInnerHTML("

This is a styled paragraph

"); diff --git a/examples/Website/frontend/main.cpp b/examples/Website/frontend/main.cpp index 739b334..fdd1d23 100644 --- a/examples/Website/frontend/main.cpp +++ b/examples/Website/frontend/main.cpp @@ -11,12 +11,11 @@ struct Note { void RenderNotes(); -// Global vector to store notes -std::vector* notes = new std::vector(); -std::vector* noteButtons = new std::vector(); +std::vector notes; +std::vector noteButtons; // Create the head section -HtmlElementView* head = new HtmlElementView("head", R"( +HtmlElementPtr head("head", R"( Note Taking App