Clone in a terminal:
Commit 78dd432
Johan Mattsson - 2026-07-14T14:08:08+00:00
78dd432758ed65060de6e42ed2c77912034572d9johan.mattsson.m@gmail.com

New component idea

Changed files (9)

Diff

diff --git a/test-for-later/attributes.rs-later b/test-for-later/attributes.rs-laternew file mode 100644index 0000000..fd5b58b--- /dev/null+++ b/test-for-later/attributes.rs-later@@ -0,0 +1,180 @@+#[path = "common.rs"]+mod common;++use kaja_web::prelude::*;+use kaja_web_component::component;+use wasm_bindgen_test::*;++use std::str::FromStr;++fn parse_value<T>(s: &str) -> Option<T>+where+    T: FromStr,+{+    s.parse::<T>().ok()+}++fn set() {+    let n: u32 = parse_value("42").unwrap();+    let f: f64 = parse_value("3.14").unwrap();+    let b: bool = parse_value("true").unwrap();+}++#[wasm_bindgen_test]+fn test_getter_and_setter() {+    common::setup_test();++    let id = "test-get-set-id";+    let content = html! {{+        <test-component2 id="$id" test_attribute="initial-value-for-attribute"></test-component1>+    }};++    inner_html("#test-div", &content).unwrap();++    {+        // borrows first time and release+        let component = TestComponent2::get_component(id).unwrap();+        let test_component = component.borrow();+        assert_eq!(test_component.test_attribute, "initial-value-for-attribute");+    }++    {+        // borrows again+        let res = TestComponent2::set_test_attribute(id, "updated-value-in-component".to_string());+        assert!(res.is_ok());+    }++    let test_attribute_from_getter = TestComponent2::get_test_attribute(id).unwrap();+    assert_eq!(test_attribute_from_getter, "updated-value-in-component");+}++//#[all_html_attributes]+#[component("test-component2")]+struct TestComponent2 {+    //#[html_attribute]+    test_attribute: String,+    //#[html_attribute]+    the_number: i32,+    not_an_attribure: String,+}++struct TestComponent2Componet {+    id: String,+    attribute_values: Rc<RefCell<TestComponent2>>,+}++impl TestComponent2Componet {+    fn set_test_attribute(&mut self, value: String) -> Option<()> {+        let el = get_element_by_id(self.id.as_str())?;++        el.set_attribute("test_attribute", &value.to_string())+            .ok()?;++        Some(())+    }++    fn get_test_attribute(&self) -> Option<String> {+        let el = get_element_by_id(self.id.as_str())?;+        let attr = el.get_attribute("test_attribute")?;+        let n: String = parse_value(&attr)?;+        Some(n)+    }++    fn set_the_number(&mut self, value: i32) -> Option<()> {+        let el = get_element_by_id(self.id.as_str())?;++        el.set_attribute("the_number", &value.to_string()).ok()?;++        Some(())+    }++    fn get_the_number(&self) -> Option<i32> {+        let el = get_element_by_id(self.id.as_str())?;+        let attr = el.get_attribute("the_number")?;+        let n: i32 = parse_value(&attr)?;+        Some(n)+    }++    fn attribute_changed_update_struct(&self, name: &str, _old_value: &str, new_value: &str) {+        log!("Attribute changed internally", name, "to", new_value);+        let component = self.attribute_values.try_borrow_mut();++        if component.is_err() {+            error!(+                "Failed to borrow component for",+                self.id, "in attribute_changed of ", name+            );+            return;+        }++        if name == "test_attribute" {+            component.unwrap().test_attribute = new_value.to_string();+        } else if name == "the_number" {+            component.unwrap().the_number = new_value.parse().unwrap();+        }+    }+}++impl Component for TestComponent2 {+    fn connected(attrib: &mut TestComponent2Componet) {+        attrib.set_test_attribute("SOME TEST".to_string());+        attrib.set_the_number(42);+    }++    fn attribute_changed(id: &str, name: &str, old_value: &str, new_value: &str) {+        Self::attribute_changed_update_struct(id, name, old_value, new_value);+        log!("Attribute changed", name, "to", new_value);+    }+}++impl TestComponent2 {+    fn connected(id: &str) {+        // might this call set_test_attribute internally because of default attributes?+    }++    fn set_test_attribute(id: &str, value: String) -> Result<()> {+        let attribute_name = "test_attribute";+        let attribute_string = value.clone();++        let element = get_element_by_id(id).ok_or(Error)?;++        return element+            .set_attribute(attribute_name, &attribute_string)+            .map_err(|_| Error);+    }++    fn get_test_attribute(id: &str) -> Option<String> {+        let component = Self::get_component(id)?;+        let test_attribute = component.borrow().test_attribute.clone();+        Some(test_attribute)+    }++    fn observed_attributes() -> &'static [&'static str] {+        &["test_attribute"]+    }++    fn attribute_changed_update_struct(id: &str, name: &str, _old_value: &str, new_value: &str) {+        log!("Attribute changed internally", name, "to", new_value);+        let component = Self::get_component(id);++        if component.is_none() {+            error!("No component found for", id);+            return;+        }++        let component = component.unwrap();+        let component = component.try_borrow_mut();++        if component.is_err() {+            error!(+                "Failed to borrow component for",+                id, "in attribute_changed of ", name+            );+            return;+        }++        if name == "test_attribute" {+            component.unwrap().test_attribute = new_value.to_string();+        }+    }+}diff --git a/test-for-later/component.rs b/test-for-later/component.rsnew file mode 100644index 0000000..f3f10e5--- /dev/null+++ b/test-for-later/component.rs@@ -0,0 +1,113 @@+#[path = "common.rs"]+mod common;++use kaja_web::prelude::*;+use kaja_web_component::component;+use wasm_bindgen_test::*;++#[wasm_bindgen_test]+fn test_component() {+    common::setup_test();++    let content = html! {{+        <test-component1></test-component1>+    }};++    try_inner_html("#test-div", &content);++    let element = get_element("test-component1").unwrap();+    let id = element.id();+    log!("id", &id);+    assert!(id.starts_with("test-component1-"));++    let component = TestComponent1::get_component(&id).unwrap();+    let test_component = component.borrow();+    assert!(test_component.tested);+}++#[wasm_bindgen_test]+fn test_custom_id() {+    common::setup_test();++    let content = html! {{+        <test-component1 id="custom-id"></test-component1>+    }};++    try_inner_html("#test-div", &content);++    let element = get_element("test-component1").unwrap();+    assert_eq!(element.id(), "custom-id");++    let component = TestComponent1::get_component("custom-id").unwrap();+    let test_component = component.borrow();+    assert!(test_component.tested);+}++#[wasm_bindgen_test]+fn test_attribute_updated() {+    common::setup_test();++    let content = html! {{+        <test-component1 id="custom-id" test_attribute="initial-value"></test-component1>+    }};++    try_inner_html("#test-div", &content);++    let element = get_element("test-component1").unwrap();++    {+        let component = TestComponent1::get_component("custom-id").unwrap();+        let test_component = component.borrow();++        assert!(test_component.tested);+        assert!(test_component.attribute_updated);+        assert_eq!(test_component.test_attribute, "initial-value"); // value on struct not on element+    }++    element+        .set_attribute("test_attribute", "updated-value")+        .unwrap();++    {+        let component = TestComponent1::get_component("custom-id").unwrap();+        let test_component = component.borrow();++        assert_eq!(test_component.test_attribute, "updated-value");+        assert!(test_component.attribute_updated);+    }+}++#[component("test-component1")]+struct TestComponent1 {+    tested: bool,+    attribute_updated: bool,++    //#[html_attribute]+    test_attribute: String,+}++impl Component for TestComponent1 {+    fn connected(id: &str) {+        let component = TestComponent1::get_component(id).unwrap();+        let mut test_component = component.borrow_mut();+        test_component.tested = true;+    }++    fn observed_attributes() -> &'static [&'static str] {+        &["test_attribute"]+    }++    fn attribute_changed(id: &str, name: &str, _old_value: &str, new_value: &str) {+        log!(+            "running attribute_changed for ",+            name,+            " new_value: ",+            new_value+        );++        let component = TestComponent1::get_component(id).unwrap();+        let mut test_component = component.borrow_mut();+        test_component.attribute_updated = true;+        test_component.test_attribute = new_value.to_string();+    }+}diff --git a/test-for-later/simple.rs b/test-for-later/simple.rsnew file mode 100644index 0000000..04c1638--- /dev/null+++ b/test-for-later/simple.rs@@ -0,0 +1,22 @@+use kaja_web::{get_cookie_value, set_cookie_value};+use wasm_bindgen_test::*;++wasm_bindgen_test_configure!(run_in_browser);++#[wasm_bindgen_test]+fn test_dom() {+    let window = web_sys::window().unwrap();+    let document = window.document().unwrap();+    assert!(document.body().is_some());+}++#[wasm_bindgen_test]+fn test_cookie() {+    set_cookie_value("test-cookie-value", "some-value").unwrap();++    let val = get_cookie_value("test-cookie-value").unwrap();+    assert_eq!(val, "some-value");++    let not_in_cookie = get_cookie_value("not-in-cookie");+    assert!(not_in_cookie.is_none());+}diff --git a/test-web.sh b/test-web.shindex a61c060..e5d9758 100755--- a/test-web.sh+++ b/test-web.sh@@ -1,4 +1,7 @@-#!/bin/bash+#!/bin/sh set -e +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)+cd "$SCRIPT_DIR"+ wasm-pack test --chrome --test alltestsdiff --git a/tests/alltests.rs b/tests/alltests.rsindex ae83f3a..ab56ae4 100644--- a/tests/alltests.rs+++ b/tests/alltests.rs@@ -5,6 +5,7 @@ pub use common::setup_test;  wasm_bindgen_test_configure!(run_in_browser); -mod attributes;-mod component;-mod simple;+//mod attributes;+//mod component;+mod componentref;+//mod simple;diff --git a/tests/attributes.rs b/tests/attributes.rsdeleted file mode 100644index fd5b58b..0000000--- a/tests/attributes.rs+++ /dev/null@@ -1,180 +0,0 @@-#[path = "common.rs"]-mod common;--use kaja_web::prelude::*;-use kaja_web_component::component;-use wasm_bindgen_test::*;--use std::str::FromStr;--fn parse_value<T>(s: &str) -> Option<T>-where-    T: FromStr,-{-    s.parse::<T>().ok()-}--fn set() {-    let n: u32 = parse_value("42").unwrap();-    let f: f64 = parse_value("3.14").unwrap();-    let b: bool = parse_value("true").unwrap();-}--#[wasm_bindgen_test]-fn test_getter_and_setter() {-    common::setup_test();--    let id = "test-get-set-id";-    let content = html! {{-        <test-component2 id="$id" test_attribute="initial-value-for-attribute"></test-component1>-    }};--    inner_html("#test-div", &content).unwrap();--    {-        // borrows first time and release-        let component = TestComponent2::get_component(id).unwrap();-        let test_component = component.borrow();-        assert_eq!(test_component.test_attribute, "initial-value-for-attribute");-    }--    {-        // borrows again-        let res = TestComponent2::set_test_attribute(id, "updated-value-in-component".to_string());-        assert!(res.is_ok());-    }--    let test_attribute_from_getter = TestComponent2::get_test_attribute(id).unwrap();-    assert_eq!(test_attribute_from_getter, "updated-value-in-component");-}--//#[all_html_attributes]-#[component("test-component2")]-struct TestComponent2 {-    //#[html_attribute]-    test_attribute: String,-    //#[html_attribute]-    the_number: i32,-    not_an_attribure: String,-}--struct TestComponent2Componet {-    id: String,-    attribute_values: Rc<RefCell<TestComponent2>>,-}--impl TestComponent2Componet {-    fn set_test_attribute(&mut self, value: String) -> Option<()> {-        let el = get_element_by_id(self.id.as_str())?;--        el.set_attribute("test_attribute", &value.to_string())-            .ok()?;--        Some(())-    }--    fn get_test_attribute(&self) -> Option<String> {-        let el = get_element_by_id(self.id.as_str())?;-        let attr = el.get_attribute("test_attribute")?;-        let n: String = parse_value(&attr)?;-        Some(n)-    }--    fn set_the_number(&mut self, value: i32) -> Option<()> {-        let el = get_element_by_id(self.id.as_str())?;--        el.set_attribute("the_number", &value.to_string()).ok()?;--        Some(())-    }--    fn get_the_number(&self) -> Option<i32> {-        let el = get_element_by_id(self.id.as_str())?;-        let attr = el.get_attribute("the_number")?;-        let n: i32 = parse_value(&attr)?;-        Some(n)-    }--    fn attribute_changed_update_struct(&self, name: &str, _old_value: &str, new_value: &str) {-        log!("Attribute changed internally", name, "to", new_value);-        let component = self.attribute_values.try_borrow_mut();--        if component.is_err() {-            error!(-                "Failed to borrow component for",-                self.id, "in attribute_changed of ", name-            );-            return;-        }--        if name == "test_attribute" {-            component.unwrap().test_attribute = new_value.to_string();-        } else if name == "the_number" {-            component.unwrap().the_number = new_value.parse().unwrap();-        }-    }-}--impl Component for TestComponent2 {-    fn connected(attrib: &mut TestComponent2Componet) {-        attrib.set_test_attribute("SOME TEST".to_string());-        attrib.set_the_number(42);-    }--    fn attribute_changed(id: &str, name: &str, old_value: &str, new_value: &str) {-        Self::attribute_changed_update_struct(id, name, old_value, new_value);-        log!("Attribute changed", name, "to", new_value);-    }-}--impl TestComponent2 {-    fn connected(id: &str) {-        // might this call set_test_attribute internally because of default attributes?-    }--    fn set_test_attribute(id: &str, value: String) -> Result<()> {-        let attribute_name = "test_attribute";-        let attribute_string = value.clone();--        let element = get_element_by_id(id).ok_or(Error)?;--        return element-            .set_attribute(attribute_name, &attribute_string)-            .map_err(|_| Error);-    }--    fn get_test_attribute(id: &str) -> Option<String> {-        let component = Self::get_component(id)?;-        let test_attribute = component.borrow().test_attribute.clone();-        Some(test_attribute)-    }--    fn observed_attributes() -> &'static [&'static str] {-        &["test_attribute"]-    }--    fn attribute_changed_update_struct(id: &str, name: &str, _old_value: &str, new_value: &str) {-        log!("Attribute changed internally", name, "to", new_value);-        let component = Self::get_component(id);--        if component.is_none() {-            error!("No component found for", id);-            return;-        }--        let component = component.unwrap();-        let component = component.try_borrow_mut();--        if component.is_err() {-            error!(-                "Failed to borrow component for",-                id, "in attribute_changed of ", name-            );-            return;-        }--        if name == "test_attribute" {-            component.unwrap().test_attribute = new_value.to_string();-        }-    }-}diff --git a/tests/component.rs b/tests/component.rsdeleted file mode 100644index f3f10e5..0000000--- a/tests/component.rs+++ /dev/null@@ -1,113 +0,0 @@-#[path = "common.rs"]-mod common;--use kaja_web::prelude::*;-use kaja_web_component::component;-use wasm_bindgen_test::*;--#[wasm_bindgen_test]-fn test_component() {-    common::setup_test();--    let content = html! {{-        <test-component1></test-component1>-    }};--    try_inner_html("#test-div", &content);--    let element = get_element("test-component1").unwrap();-    let id = element.id();-    log!("id", &id);-    assert!(id.starts_with("test-component1-"));--    let component = TestComponent1::get_component(&id).unwrap();-    let test_component = component.borrow();-    assert!(test_component.tested);-}--#[wasm_bindgen_test]-fn test_custom_id() {-    common::setup_test();--    let content = html! {{-        <test-component1 id="custom-id"></test-component1>-    }};--    try_inner_html("#test-div", &content);--    let element = get_element("test-component1").unwrap();-    assert_eq!(element.id(), "custom-id");--    let component = TestComponent1::get_component("custom-id").unwrap();-    let test_component = component.borrow();-    assert!(test_component.tested);-}--#[wasm_bindgen_test]-fn test_attribute_updated() {-    common::setup_test();--    let content = html! {{-        <test-component1 id="custom-id" test_attribute="initial-value"></test-component1>-    }};--    try_inner_html("#test-div", &content);--    let element = get_element("test-component1").unwrap();--    {-        let component = TestComponent1::get_component("custom-id").unwrap();-        let test_component = component.borrow();--        assert!(test_component.tested);-        assert!(test_component.attribute_updated);-        assert_eq!(test_component.test_attribute, "initial-value"); // value on struct not on element-    }--    element-        .set_attribute("test_attribute", "updated-value")-        .unwrap();--    {-        let component = TestComponent1::get_component("custom-id").unwrap();-        let test_component = component.borrow();--        assert_eq!(test_component.test_attribute, "updated-value");-        assert!(test_component.attribute_updated);-    }-}--#[component("test-component1")]-struct TestComponent1 {-    tested: bool,-    attribute_updated: bool,--    //#[html_attribute]-    test_attribute: String,-}--impl Component for TestComponent1 {-    fn connected(id: &str) {-        let component = TestComponent1::get_component(id).unwrap();-        let mut test_component = component.borrow_mut();-        test_component.tested = true;-    }--    fn observed_attributes() -> &'static [&'static str] {-        &["test_attribute"]-    }--    fn attribute_changed(id: &str, name: &str, _old_value: &str, new_value: &str) {-        log!(-            "running attribute_changed for ",-            name,-            " new_value: ",-            new_value-        );--        let component = TestComponent1::get_component(id).unwrap();-        let mut test_component = component.borrow_mut();-        test_component.attribute_updated = true;-        test_component.test_attribute = new_value.to_string();-    }-}diff --git a/tests/componentref.rs b/tests/componentref.rsnew file mode 100644index 0000000..17d3bfb--- /dev/null+++ b/tests/componentref.rs@@ -0,0 +1,133 @@+#[path = "common.rs"]+mod common;++use kaja_web::prelude::*;+use kaja_web_component::component;+use wasm_bindgen_test::*;++use std::rc::Rc;+use std::str::FromStr;++thread_local! {+    static TEST2_COMPONENTS: RefCell<HashMap<String, Test2Handle>> =+        RefCell::new(HashMap::new());+}++fn parse_value<T>(s: &str) -> Option<T>+where+    T: FromStr,+{+    s.parse::<T>().ok()+}++#[wasm_bindgen_test]+fn test_new_component() {+    common::setup_test();++    create_test2();++    let id = "test-get-set-id";++    let content = html! {{+        <test-component2 id="$id" test_attribute="initial-value-for-attribute"></test-component1>+    }};++    inner_html("#test-div", &content).unwrap();+    let component = Test2Component::get_component(id); // ref+}++fn create_test2() {+    let handle = Rc::new(RefCell::new(Test2ActualContainer {+        id: "test2".to_string(),+        attribute_values: Rc::new(RefCell::new(Test2::default())),+    }));++    register_component(handle.clone());+    Test2ActualContainer::connect(handle);+}++fn register_component(component: Test2Handle) {+    let id = component.borrow().id.clone();++    TEST2_COMPONENTS.with(|components| {+        components.borrow_mut().insert(id, component);+    });+}++#[derive(Default)]+struct Test2 {+    test: bool,+}++struct Test2ActualContainer {+    id: String,+    attribute_values: Rc<RefCell<Test2>>,+}++type Test2Handle = Rc<RefCell<Test2ActualContainer>>;++impl Test2ActualContainer {+    fn connect(handle: Test2Handle) {}+    fn attributes_update(&self, name: &str, old_value: &str, new_value: &str) {}+    fn set_test_attribute() {}+    fn get_test_attribute(&self) -> String {+        String::from("test ...")+    }+}++struct Test2Component {+    handle: Test2Handle,+}++impl Test2Component {+    fn connect(&self) {}+    fn get_component(id: &str) -> Option<Test2Component> {+        let handle = TEST2_COMPONENTS.with(|components| components.borrow().get(id).cloned());++        if !handle.is_some() {+            return None;+        }++        Some(Test2Component {+            handle: handle.unwrap(),+        })+    }++    fn attributes_update(&self, name: &str, old_value: &str, new_value: &str) {+        self.handle+            .borrow()+            .attributes_update(name, old_value, new_value);+    }++    fn set_test_attribute(&self, name: &str, value: &str) {}++    fn get_test_attribute(&self) -> String {+        String::from("test ...")+    }++    fn get_attributes(&self) -> Rc<RefCell<Test2>> {+        self.handle.borrow().attribute_values.clone()+    }++    fn with_attributes_mut<F>(&self, f: F)+    where+        F: FnOnce(&mut Test2),+    {+        let handle = self.handle.borrow();+        let mut attributes = handle.attribute_values.borrow_mut();+        f(&mut attributes);+    }++    fn with_attributes<F>(&self, f: F)+    where+        F: FnOnce(&Test2),+    {+        let handle = self.handle.borrow();+        let attributes = handle.attribute_values.borrow();+        f(&attributes);+    }++    fn get_id(&self) -> String {+        self.handle.borrow().id.clone()+    }+}diff --git a/tests/simple.rs b/tests/simple.rsdeleted file mode 100644index 04c1638..0000000--- a/tests/simple.rs+++ /dev/null@@ -1,22 +0,0 @@-use kaja_web::{get_cookie_value, set_cookie_value};-use wasm_bindgen_test::*;--wasm_bindgen_test_configure!(run_in_browser);--#[wasm_bindgen_test]-fn test_dom() {-    let window = web_sys::window().unwrap();-    let document = window.document().unwrap();-    assert!(document.body().is_some());-}--#[wasm_bindgen_test]-fn test_cookie() {-    set_cookie_value("test-cookie-value", "some-value").unwrap();--    let val = get_cookie_value("test-cookie-value").unwrap();-    assert_eq!(val, "some-value");--    let not_in_cookie = get_cookie_value("not-in-cookie");-    assert!(not_in_cookie.is_none());-}

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112