Commit 3a11c28
More documentation
Changed files (3)
Diff
@@ -8,8 +8,5 @@ charset = utf-8 end_of_line = lf trim_trailing_whitespace = true -[Makefile]-indent_style = tab- [*.md] trim_trailing_whitespace = false@@ -1,16 +1,16 @@-# Web Framework: kaja-web – for Web Applications written in Rust+# kaja-web – A Framework for Web Applications Written in Rust The key concept and idea behind the design is that HTML content is managed as strings and the code is compiled to WebAssembly. There is no Domain Specific-Language, just plain Rust with a little bit of glue code that calls the WebAssembly-functions in onclick handlers (and also other event handlers).+Language, just plain Rust with a little bit of glue code that calls the+WebAssembly functions in onclick handlers (and also other event handlers). -There are also a number of helper functions available to make it easier to interact-with the browser.+There are also a number of helper functions available to make it easier to+interact with the browser. -No state changes triggers re-render automatically, run the update function-manually when you want to render a component and use `inner_html("#the-id", content)`-to update the DOM.+No state changes triggers re-render automatically, run your update function +manually when you want to render a component and use +`inner_html("#the-id", content)` to update the DOM. ## Example: ```rust@@ -42,7 +42,7 @@ fn update_counter_display(app_data: &AppData) { fn main() { init_callbacks(); - let mut app_data = APP_DATA.write().unwrap();+ let mut app_data = APP_DATA.read().unwrap(); update_counter_display(&app_data); } ```@@ -52,7 +52,7 @@ This example requres an html file with this content: <div class="main-content"></div> ``` -See examples/clickcounter for full example.+See examples/clickcounter for a full example. # Passing Objects from JS Callbacks to Rust WASM @@ -61,7 +61,6 @@ This requires `serde::Deserialize;`. ```rust use kaja_web::prelude::*; use serde::Deserialize;-use web_sys::KeyboardEvent; #[derive(Deserialize)] pub struct TestData {@@ -78,9 +77,7 @@ fn update_component() { #[callback(foo)] fn foo(data: TestData) {- let mut app_data = APP_DATA.write().unwrap();- app_data.current_count += 1;- update_counter_display(&app_data);+ log!("test_parameter: {}", data.test_parameter); } ``` @@ -89,6 +86,49 @@ The HTML code is generated using the `kaja-html-macro` crate. The callback functions are definedusing the `kaja-callback-macro` crate. Helper functions are added in this crate and reexportedfrom the `kaja_web::prelude` module. +## Building WASM Packages++```bash+cargo build++wasm-pack build \+ --release \+ --target web \+ --out-dir pkg \+ --out-name main \+ --no-typescript++cp index.html pkg/+cp loader.js pkg/+cp styles.css pkg/+```++## Loading the WASM Package with JavaScript++See examples for complete examples with WebAssembly, html and JavaScript.++```javascript+let wasmModule;++async function loadWasm() {+ try {+ const wasmModule = await import("./main.js");+ await wasmModule.default("./main_bg.wasm");++ return wasmModule;+ } catch (error) {+ console.error("Failed to load WASM module:", error);+ }++ return null;+}++window.addEventListener("DOMContentLoaded", async () => {+ wasmModule = await loadWasm();+});+```++ ## Author and Contact - Written by Johan Mattsson - johan.mattsson.m@gmail.com@@ -22,8 +22,9 @@ unsafe impl Sync for CallbackRegistration {} inventory::collect!(CallbackRegistration); -/// Register callbacks that can be used in JS to run Rust functions in the WASM bundle.-/// This needs to run when the WASM bundle is loaded.+/// Register callbacks that can be used in JS to run Rust functions in the WASM+/// module. This needs to run when the WASM bundle is loaded.+/// /// ```rust /// #[wasm_bindgen(start)] /// pub fn init() {@@ -31,7 +32,11 @@ inventory::collect!(CallbackRegistration); /// } /// ``` ///-/// The Rust functions is marked with the `#[callback]` attribut.+/// The Rust functions as marked with the `#[callback]` attribute in order to+/// be callable from JS. The JS function in this example has the name+/// `testCallback`. Note that camel case is used in JS and regular snake case+/// is used in Rust for the same function.+/// /// ```rust /// #[callback(testCallback)] /// pub fn test_callback() {@@ -79,7 +84,8 @@ pub fn get_element(selector: &str) -> Option<HtmlElement> { None } -/// Queries the document for all elements matching the given selector.+/// Returns all elements matching the given selector.+/// For example, `get_elements(".test")` would return all elements with the class `test`. pub fn get_elements(selector: &str) -> Vec<HtmlElement> { let window = web_sys::window(); @@ -149,7 +155,15 @@ pub fn inner_text(selector: &str, text: &str) -> Result<()> { Ok(()) } -/// Get value from input tag+/// Get value from an input tag.+/// ```html+/// <input type="text" id="test" value="test value" />+/// ```+///+/// ```rust+/// let value = get_value("#test");+/// assert_eq!(value, Some("test value"));+/// ``` pub fn get_value(selector: &str) -> Option<String> { let element = get_element(selector)?; @@ -166,12 +180,12 @@ pub fn try_get_value(selector: &str) -> String { return value.unwrap_or_default(); } -/// Sets the inner HTML of the first element matching the given selector, if one exists.+/// Sets the inner HTML of elements matching the given selector, if at least one exists. pub fn try_inner_html(selector: &str, html: &str) { let _ = inner_html(selector, html); } -/// Sets the inner text of the first element matching the given selector, if one exists.+/// Sets the inner text of elements matching the given selector, if at least one exists. pub fn try_inner_text(selector: &str, text: &str) { let _ = inner_text(selector, text); }