mirror of
https://github.com/zaphar/wasm-web-components.git
synced 2025-07-21 19:40:30 -04:00
Initial javascript shim working
This commit is contained in:
commit
3d2a1a285e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Cargo.lock
|
39
Cargo.toml
Normal file
39
Cargo.toml
Normal file
@ -0,0 +1,39 @@
|
||||
[package]
|
||||
name = "web-component-rs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
author = "Jeremy Wall <jeremy@marzhillstudios.com>"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies.wasm-bindgen-test]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.wasm-bindgen]
|
||||
version = "= 0.2.81"
|
||||
|
||||
[dependencies.js-sys]
|
||||
version = "0.3"
|
||||
|
||||
[dependencies.web-sys]
|
||||
version = "0.3"
|
||||
features = [
|
||||
"CustomElementRegistry",
|
||||
"Document",
|
||||
#"DocumentFragment",
|
||||
"KeyboardEvent",
|
||||
"Event",
|
||||
"EventTarget",
|
||||
"Element",
|
||||
"HtmlBaseElement",
|
||||
"HtmlElement",
|
||||
"HtmlTemplateElement",
|
||||
"HtmlSlotElement",
|
||||
"Node",
|
||||
"ShadowRoot",
|
||||
"ShadowRootInit",
|
||||
"ShadowRootMode",
|
||||
"Window",
|
||||
]
|
73
src/lib.rs
Normal file
73
src/lib.rs
Normal file
@ -0,0 +1,73 @@
|
||||
use js_sys::Function;
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::window;
|
||||
|
||||
type Result<T> = std::result::Result<T, JsValue>;
|
||||
|
||||
pub trait CustomElementImpl {
|
||||
fn class_name() -> &'static str;
|
||||
fn element_name() -> &'static str;
|
||||
}
|
||||
|
||||
pub fn define_web_component<T: CustomElementImpl>() -> Result<JsValue> {
|
||||
let body = format!(
|
||||
"class {name} extends HTMLElement {{
|
||||
constructor() {{
|
||||
super();
|
||||
}}
|
||||
}}
|
||||
customElements.define(\"{element_name}\", {name});
|
||||
var element = customElements.get(\"{element_name}\");
|
||||
return element;",
|
||||
name = T::class_name(),
|
||||
element_name = T::element_name(),
|
||||
);
|
||||
let fun = Function::new_no_args(&body);
|
||||
Ok(fun.call0(&window().unwrap())?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
use wasm_bindgen_test::wasm_bindgen_test;
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
pub struct MyElementImpl();
|
||||
|
||||
impl CustomElementImpl for MyElementImpl {
|
||||
fn class_name() -> &'static str {
|
||||
"MyElement"
|
||||
}
|
||||
|
||||
fn element_name() -> &'static str {
|
||||
"my-element"
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||
pub fn log(message: String);
|
||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||
pub fn log_with_val(message: String, val: &JsValue);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn test_component_definition() {
|
||||
let obj = define_web_component::<MyElementImpl>().expect("Failed to define web component");
|
||||
let fun = obj.dyn_ref::<Function>().unwrap();
|
||||
assert_eq!(fun.name(), MyElementImpl::class_name());
|
||||
|
||||
let element = window()
|
||||
.unwrap()
|
||||
.document()
|
||||
.unwrap()
|
||||
.create_element(MyElementImpl::element_name())
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
element.tag_name().to_uppercase(),
|
||||
MyElementImpl::element_name().to_uppercase()
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user