Skip to main content

fusor/dom/
target.rs

1//! Native handles are the binding interface. Selectors are a convenience adapter.
2
3use super::{JsValue, Scope};
4use wasm_bindgen::JsCast;
5use web_sys::{Element, HtmlInputElement};
6
7/// An element handle, or a selector resolved relative to a scope.
8pub trait ElementTarget {
9    fn resolve(self, scope: &Scope) -> Result<Element, JsValue>;
10}
11
12/// A native input handle, or a selector checked to refer to an input.
13/// Passing an unrelated element handle is a Rust type error.
14pub trait InputTarget {
15    fn resolve_input(self, scope: &Scope) -> Result<HtmlInputElement, JsValue>;
16}
17
18impl ElementTarget for &str {
19    fn resolve(self, scope: &Scope) -> Result<Element, JsValue> {
20        scope.select(self)
21    }
22}
23
24impl InputTarget for &str {
25    fn resolve_input(self, scope: &Scope) -> Result<HtmlInputElement, JsValue> {
26        scope
27            .select(self)?
28            .dyn_into()
29            .map_err(|_| JsValue::from_str("fusor: input binding requires an HTML input element"))
30    }
31}
32
33impl ElementTarget for &String {
34    fn resolve(self, scope: &Scope) -> Result<Element, JsValue> {
35        self.as_str().resolve(scope)
36    }
37}
38
39impl InputTarget for &String {
40    fn resolve_input(self, scope: &Scope) -> Result<HtmlInputElement, JsValue> {
41        self.as_str().resolve_input(scope)
42    }
43}
44
45impl ElementTarget for &Element {
46    fn resolve(self, _: &Scope) -> Result<Element, JsValue> {
47        Ok(self.clone())
48    }
49}
50
51impl ElementTarget for &HtmlInputElement {
52    fn resolve(self, _: &Scope) -> Result<Element, JsValue> {
53        Ok(self.clone().into())
54    }
55}
56
57impl InputTarget for &HtmlInputElement {
58    fn resolve_input(self, _: &Scope) -> Result<HtmlInputElement, JsValue> {
59        Ok(self.clone())
60    }
61}