custom_element/
create_custom_element.rs1use js_sys::{Array, Function};
2use wasm_bindgen::prelude::*;
3
4use crate::{constructors::HTML_ELEMENT_CONSTRUCTOR, Bridge, CustomElement, GeneratedConstructor};
5
6type MakeStruct = Closure<dyn FnMut(JsValue, Array) -> JsValue>;
7
8#[wasm_bindgen(module = "/src/createCustomElement.js")]
10extern "C" {
11 #[wasm_bindgen(js_name = createCustomElement)]
12 pub(self) fn _create_custom_element(
13 make_rust_struct: &MakeStruct,
14 attributes: Vec<String>,
15 constructor: &Function,
16 ) -> Function;
17}
18
19#[derive(Copy, Clone, Eq, PartialEq, Debug)]
23pub struct CustomElementConfiguration<'a> {
24 pub element_constructor: &'a Function,
26}
27
28impl Default for CustomElementConfiguration<'_> {
29 fn default() -> Self {
30 Self {
31 element_constructor: &HTML_ELEMENT_CONSTRUCTOR,
32 }
33 }
34}
35
36pub struct CustomElementResult {
38 pub constructor: GeneratedConstructor,
41
42 pub closure: MakeStruct,
49}
50
51pub fn create_custom_element<
53 C: CustomElement + 'static,
54 F: FnMut(JsValue, Array) -> C + 'static,
55>(
56 create_cutom_element: F,
57 attributes: Vec<String>,
58) -> (MakeStruct, GeneratedConstructor) {
59 let config = CustomElementConfiguration::default();
60 create_custom_element_with_config(create_cutom_element, attributes, config)
61}
62
63pub fn create_custom_element_with_config<
65 C: CustomElement + 'static,
66 F: FnMut(JsValue, Array) -> C + 'static,
67>(
68 mut create_cutom_element: F,
69 attributes: Vec<String>,
70 config: CustomElementConfiguration,
71) -> (MakeStruct, GeneratedConstructor) {
72 let closure = Closure::new(move |element, args| {
73 let bridge: Bridge = create_cutom_element(element, args).into();
74 bridge.into()
75 });
76 let class = _create_custom_element(&closure, attributes, config.element_constructor);
77 (closure, GeneratedConstructor(class))
78}