web-sys
The web-sys
crate provides bindings for Web APIs. This is
procedurally generated from browser WebIDL which is why some names are so long and why some types are vague.
Features in web-sys
The web-sys
crate with all of it's features enabled can add lots of bloat to a Wasm application,
in order to get around this issue most types are feature gated so that you only include the types
you require for your application. Yew includes a number of features from web-sys
and
exposes some types in it's public API, you will often need to add web-sys
as a dependency yourself.
Inheritance in web-sys
In the Simulating inheritance section you can read how in
general Rust provides an approach to simulate inheritance in JavaScript. This is very important in
web-sys
as understanding what methods are available on a type means understanding it's inheritance.
This section is going to look at a specific element and list out it's inheritance using Rust by
calling Deref::deref
until
the value is JsValue
:
use std::ops::Deref;
use web_sys::{
Element,
EventTarget,
HtmlElement,
HtmlTextAreaElement,
Node,
};
fn inheritance_of_text_area(text_area: HtmlTextAreaElement) {
// HtmlTextAreaElement is <textarea> in html.
let html_element: &HtmlElement = text_area.deref();
let element: &Element = html_element.deref();
let node: &Node = element.deref();
let event_target: &EventTarget = node.deref();
// Notice we've moved from web-sys types now into built-in
// JavaScript types which are in the js-sys crate.
let object: &js_sys::Object = event_target.deref();
// Notice we've moved from js-sys type to the root JsValue from
// the wasm-bindgen crate.
let js_value: &wasm_bindgen::JsValue = object.deref();
// Using deref like this means we have to manually traverse
// the inheritance tree, however, you can call JsValue methods
// on the HtmlTextAreaElement type.
// The `is_string` method comes from JsValue.
assert!(!text_area.is_string());
// empty function just to prove we can pass HtmlTextAreaElement as a
// &EventTarget.
fn this_function_only_takes_event_targets(targets: &EventTarget) {};
// The compiler will walk down the deref chain in order to match the types here.
this_function_only_takes_event_targets(&text_area);
// The AsRef implementations allow you to treat the HtmlTextAreaElement
// as an &EventTarget.
let event_target: &EventTarget = text_area.as_ref();
}
Inheritance in web-sys
in The wasm-bindgen
Guide.
The Node
in NodeRef
Yew uses a NodeRef
in order to provide a way for keeping a reference to
a Node
made by the html!
macro. The Node
part of NodeRef
is referring to
web_sys::Node
. The
NodeRef::get
method will return a Option<Node>
value, however, most of the time in Yew you want
to cast this value to a specific element so you can use it's specific methods. This casting
can be done using JsCast
on the Node
value, if present, but Yew
provides the NodeRef::cast
method to perform this casting for convenience and so that you don't
necessarily have to include the wasm-bindgen
dependency for the JsCast
trait.
The two code blocks below do essentially the same thing, the first is using NodeRef::cast
and
the second is using JsCast::dyn_into
on the web_sys::Node
returned from NodeRef::get
.
- Using NodeRef::cast
- Using NodeRef::get
use web_sys::HtmlInputElement;
use yew::NodeRef;
fn with_node_ref_cast(node_ref: NodeRef) {
if let Some(input) = node_ref.cast::<HtmlInputElement>() {
// do something with HtmlInputElement
}
}