web-dom

DOM access for web assembly * no magic * no abstractions * no code generation * api generated from webidl * can be used with many languages that compile to web assembly

Features: * [x] dom * [x] events * [x] canvas * [x] localStorage * [x] webgl * [ ] audio * [ ] networking

Documentation: https://docs.rs/web-dom/

toml web-dom = "0.1"

Want to create web components? Check out https://github.com/web-dom/webcomponent

```rust use web_dom::*;

[no_mangle]

pub fn main() -> () { console::log("hello world") } html

toml [package] name = "helloworld" version = "0.0.1" edition = "2018"

[lib] crate-type =["cdylib"]

[dependencies] web-dom = "0.1" console cargo build --target wasm32-unknown-unknown --release ```

See it working here

Alert

```rust use web_dom::*;

[no_mangle]

pub fn main() -> () { window::alert(window(),"hello world!"); } ```

See it working here

Canvas

```rust use web_dom::*;

[no_mangle]

pub fn main() -> () { let doc = window::getdocument(window()); let canvas = document::queryselector(doc,"#screen"); let ctx = htmlcanvas::getcontext(canvas,"2d"); canvas::fillrect(ctx,0.0,0.0,50.0,50.0); } ```

See it working here

Events

```rust use web_dom::*;

[no_mangle]

pub fn callback(listener:EventListener,event:Event) -> () { let input = document::queryselector(document(),"input"); let msg = htmlinput::getvalue(input); window::alert(window(),&msg); }

[no_mangle]

pub fn main() -> () { let btn = document::queryselector(document(),"button"); let listener = createeventlistener(); eventtarget::addevent_listener(btn,"click",listener); } ```

See it working here

Pong

https://github.com/richardanaya/pong/

See it working here

Don't like Rust?

web-dom can be used with any language that compiles to web assembly

```C extern int globalwindow(); extern void windowalert(char*);

int main(void) { windowalert(globalwindow(),"hello world!"); } ```

```clojure (extern globalgetwindow []) (extern windowgetdocument [window]) (extern documentqueryselector [document query]) (extern htmlcanvasgetcontext [element context]) (extern drawingsetfillstyle [canvas color]) (extern drawingfill_rect [canvas x y w h])

(def colors ("black" "grey" "red"))

(pub defn main [] (let [window (globalgetwindow) document (windowgetdocument window) canvas (documentqueryselector document "#screen") ctx (htmlcanvasgetcontext canvas "2d")] (loop [x 0] (if (< x 3) (do (drawingsetfillstyle ctx (mem32 (+ colors (* 4 x)))) (drawingfill_rect ctx (* x 10) (* x 10) 50 50 ) (recur [x (+ x 1)])))))) ```

Want to add your own functions?

Do you need a function I haven't provided? You can easily add your own function to your module context by calling WebDOM imperatively.

WebDOM.run("my.wasm",{ my_function: function(){ } }

Dynamic Calls

In some situations your application may need to utilize behavior in external web assembly modules. Imagine for instance a library called calculator.wasm that knows how to do calculations for me. I can dynamically call an exported function on the module like so.

```rust use web_dom::*;

fn add(calc:DOMReference, a:i32,b:i32) -> i32{ let dyncall = dynamic::begin(calc); dynamic::parami32(dyncall,a); dynamic::parami32(dyncall,b); dynamic::call(dyncall,"add"); let result = dynamic::resulti32(dyncall); dynamic::unload(calc); result }

[no_mangle]

pub fn callback(listener: EventListener, event: Event) -> () { // get a handle to the module let calc = getproperty(event,"module"); // call add let result = add(calc,2,2); console::log(&format!("{}",result)); }

[no_mangle]

pub fn main() -> () { // Load web module asynchronously let loadlistener = createeventlistener(); dynamic::load("calculator.wasm",loadlistener); } ```

This approach has quite a lot of ceremony to it, but can enable some very powerful multi-language projects. It's intended to be used for big libraries you wouldn't want to compile in yourself, libraries written in another language, or proprietary libraries.