Skip to content

Commit

Permalink
Merge pull request rustwasm#997 from jonathanKingston/todo-clean
Browse files Browse the repository at this point in the history
Remove compiler warnings in todo example
  • Loading branch information
alexcrichton authored Nov 27, 2018
2 parents 6fd33a7 + d59716b commit 4a70198
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 142 deletions.
1 change: 1 addition & 0 deletions examples/todomvc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ askama = "0.7.2"
js-sys = "0.3.5"
wasm-bindgen = "0.2.28"
askama = "0.7.2"
console_error_panic_hook = "0.1"

[dependencies.web-sys]
version = "0.3.4"
Expand Down
13 changes: 5 additions & 8 deletions examples/todomvc/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,11 @@ impl Controller {
/// Set all items to complete or active.
fn toggle_all(&mut self, completed: bool) {
let mut vals = Vec::new();
self.store
.find(
ItemQuery::EmptyItemQuery,
).map(|data| {
for item in data.iter() {
vals.push(item.id.clone());
}
});
self.store.find(ItemQuery::EmptyItemQuery).map(|data| {
for item in data.iter() {
vals.push(item.id.clone());
}
});
for id in vals.iter() {
self.toggle_completed(id.to_string(), completed);
}
Expand Down
181 changes: 161 additions & 20 deletions examples/todomvc/src/element.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::EventTarget;

/// Wrapper for `web_sys::Element` to simplify calling different interfaces
pub struct Element {
el: Option<web_sys::Element>,
}

impl From<web_sys::Element> for Element {
fn from(el: web_sys::Element) -> Element {
Element { el: Some(el) }
}
}

impl From<web_sys::EventTarget> for Element {
fn from(el: web_sys::EventTarget) -> Element {
let el = wasm_bindgen::JsCast::dyn_into::<web_sys::Element>(el);
Element { el: el.ok() }
}
}

impl From<Element> for Option<web_sys::Node> {
fn from(obj: Element) -> Option<web_sys::Node> {
if let Some(el) = obj.el {
Expand All @@ -17,8 +31,8 @@ impl From<Element> for Option<web_sys::Node> {
}
}

impl From<Element> for Option<web_sys::EventTarget> {
fn from(obj: Element) -> Option<web_sys::EventTarget> {
impl From<Element> for Option<EventTarget> {
fn from(obj: Element) -> Option<EventTarget> {
if let Some(el) = obj.el {
Some(el.into())
} else {
Expand All @@ -28,6 +42,15 @@ impl From<Element> for Option<web_sys::EventTarget> {
}

impl Element {
// Create an element from a tag name
pub fn create_element(tag: &str) -> Option<Element> {
if let Some(el) = web_sys::window()?.document()?.create_element(tag).ok() {
Some(el.into())
} else {
None
}
}

pub fn qs(selector: &str) -> Option<Element> {
let body: web_sys::Element = web_sys::window()?.document()?.body()?.into();
let el = body.query_selector(selector).ok()?;
Expand All @@ -41,8 +64,10 @@ impl Element {
{
let cb = Closure::wrap(Box::new(handler) as Box<FnMut(_)>);
if let Some(el) = self.el.take() {
let el_et: web_sys::EventTarget = el.into();
el_et.add_event_listener_with_callback(event_name, cb.as_ref().unchecked_ref());
let el_et: EventTarget = el.into();
el_et
.add_event_listener_with_callback(event_name, cb.as_ref().unchecked_ref())
.unwrap();
cb.forget();
if let Ok(el) = el_et.dyn_into::<web_sys::Element>() {
self.el = Some(el);
Expand All @@ -64,22 +89,18 @@ impl Element {
Some(e) => e,
None => return,
};
if let Some(dyn_el) = &el.dyn_ref::<web_sys::EventTarget>()
{
if let Some(dyn_el) = &el.dyn_ref::<EventTarget>() {
if let Some(window) = web_sys::window() {
if let Some(document) = window.document() {
// TODO document selector to the target element
let tg_el = document;

let cb = Closure::wrap(Box::new(move |event: web_sys::Event| {
if let Some(target_element) = event.target() {
let dyn_target_el: Option<
&web_sys::Node,
> = wasm_bindgen::JsCast::dyn_ref(&target_element);
let dyn_target_el: Option<&web_sys::Node> =
wasm_bindgen::JsCast::dyn_ref(&target_element);
if let Some(target_element) = dyn_target_el {
if let Ok(potential_elements) =
tg_el.query_selector_all(selector)
{
if let Ok(potential_elements) = tg_el.query_selector_all(selector) {
let mut has_match = false;
for i in 0..potential_elements.length() {
if let Some(el) = potential_elements.get(i) {
Expand All @@ -98,11 +119,13 @@ impl Element {
}
}) as Box<FnMut(_)>);

dyn_el.add_event_listener_with_callback_and_bool(
event,
cb.as_ref().unchecked_ref(),
use_capture,
);
dyn_el
.add_event_listener_with_callback_and_bool(
event,
cb.as_ref().unchecked_ref(),
use_capture,
)
.unwrap();
cb.forget(); // TODO cycle collect
}
}
Expand Down Expand Up @@ -138,6 +161,43 @@ impl Element {
}
}

/// Gets the text content of the `self.el` element
pub fn text_content(&mut self) -> Option<String> {
let mut text = None;
if let Some(el) = self.el.as_ref() {
if let Some(node) = &el.dyn_ref::<web_sys::Node>() {
text = node.text_content();
}
}
text
}

/// Gets the parent of the `self.el` element
pub fn parent_element(&mut self) -> Option<Element> {
let mut parent = None;
if let Some(el) = self.el.as_ref() {
if let Some(node) = &el.dyn_ref::<web_sys::Node>() {
if let Some(parent_node) = node.parent_element() {
parent = Some(parent_node.into());
}
}
}
parent
}

/// Gets the parent of the `self.el` element
pub fn append_child(&mut self, child: &mut Element) {
if let Some(el) = self.el.as_ref() {
if let Some(node) = &el.dyn_ref::<web_sys::Node>() {
if let Some(ref child_el) = child.el {
if let Some(child_node) = child_el.dyn_ref::<web_sys::Node>() {
node.append_child(child_node).unwrap();
}
}
}
}
}

/// Removes a class list item from the element
///
/// ```
Expand All @@ -146,7 +206,14 @@ impl Element {
/// ```
pub fn class_list_remove(&mut self, value: &str) {
if let Some(el) = self.el.take() {
el.class_list().remove_1(&value);
el.class_list().remove_1(&value).unwrap();
self.el = Some(el);
}
}

pub fn class_list_add(&mut self, value: &str) {
if let Some(el) = self.el.take() {
el.class_list().add_1(&value).unwrap();
self.el = Some(el);
}
}
Expand All @@ -158,7 +225,7 @@ impl Element {
if let Some(el) = self.el.take() {
if let Some(el_node) = el.dyn_ref::<web_sys::Node>() {
let child_node: web_sys::Node = child_el.into();
el_node.remove_child(&child_node);
el_node.remove_child(&child_node).unwrap();
}
self.el = Some(el);
}
Expand Down Expand Up @@ -186,7 +253,57 @@ impl Element {
}
}

/// Sets the visibility for the element in `self.el` (The element must be an input)
pub fn blur(&mut self) {
if let Some(el) = self.el.take() {
{
let dyn_el: Option<&web_sys::HtmlElement> = wasm_bindgen::JsCast::dyn_ref(&el);
if let Some(el) = dyn_el {
// There isn't much we can do with the result here so ignore
el.blur().unwrap();
}
}
self.el = Some(el);
}
}

pub fn focus(&mut self) {
if let Some(el) = self.el.take() {
{
let dyn_el: Option<&web_sys::HtmlElement> = wasm_bindgen::JsCast::dyn_ref(&el);
if let Some(el) = dyn_el {
// There isn't much we can do with the result here so ignore
el.focus().unwrap();
}
}
self.el = Some(el);
}
}

pub fn dataset_set(&mut self, key: &str, value: &str) {
if let Some(el) = self.el.take() {
{
if let Some(el) = wasm_bindgen::JsCast::dyn_ref::<web_sys::HtmlElement>(&el) {
el.dataset().set(key, value).unwrap();
}
}
self.el = Some(el);
}
}

pub fn dataset_get(&mut self, key: &str) -> String {
let mut text = String::new();
if let Some(el) = self.el.take() {
{
if let Some(el) = wasm_bindgen::JsCast::dyn_ref::<web_sys::HtmlElement>(&el) {
text = el.dataset().get(key);
}
}
self.el = Some(el);
}
text
}

/// Sets the value for the element in `self.el` (The element must be an input)
pub fn set_value(&mut self, value: &str) {
if let Some(el) = self.el.take() {
if let Some(el) = wasm_bindgen::JsCast::dyn_ref::<web_sys::HtmlInputElement>(&el) {
Expand All @@ -196,6 +313,18 @@ impl Element {
}
}

/// Gets the value for the element in `self.el` (The element must be an input)
pub fn value(&mut self) -> String {
let mut v = String::new();
if let Some(el) = self.el.take() {
if let Some(el) = wasm_bindgen::JsCast::dyn_ref::<web_sys::HtmlInputElement>(&el) {
v = el.value();
}
self.el = Some(el);
}
v
}

/// Sets the checked state for the element in `self.el` (The element must be an input)
pub fn set_checked(&mut self, checked: bool) {
if let Some(el) = self.el.take() {
Expand All @@ -205,4 +334,16 @@ impl Element {
self.el = Some(el);
}
}

/// Gets the checked state for the element in `self.el` (The element must be an input)
pub fn checked(&mut self) -> bool {
let mut checked = false;
if let Some(el) = self.el.take() {
if let Some(el) = wasm_bindgen::JsCast::dyn_ref::<web_sys::HtmlInputElement>(&el) {
checked = el.checked();
}
self.el = Some(el);
}
checked
}
}
3 changes: 2 additions & 1 deletion examples/todomvc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! # TODO MVC
//!
//! A [TODO MVC](https://todomvc.com/) implementation written using [web-sys](https://rustwasm.github.io/wasm-bindgen/web-sys/overview.html)
#![warn(missing_docs)]

extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
Expand All @@ -11,6 +10,7 @@ extern crate web_sys;
use std::rc::Rc;

extern crate askama;
extern crate console_error_panic_hook;

/// Controller of the program
pub mod controller;
Expand Down Expand Up @@ -65,5 +65,6 @@ fn app(name: &str) {
/// Entry point into the program from JavaScript
#[wasm_bindgen]
pub fn run() {
console_error_panic_hook::set_once();
app("todos-wasmbindgen");
}
16 changes: 10 additions & 6 deletions examples/todomvc/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ impl Store {
if let Ok(storage_string) = JSON::stringify(&JsValue::from(array)) {
let storage_string: String = storage_string.to_string().into();
self.local_storage
.set_item(&self.name, storage_string.as_str());
.set_item(&self.name, storage_string.as_str())
.unwrap();
}
}

Expand All @@ -82,7 +83,12 @@ impl Store {
/// // data will contain items whose completed properties are true
/// ```
pub fn find(&mut self, query: ItemQuery) -> Option<ItemListSlice> {
Some(self.data.iter().filter(|todo| query.matches(*todo)).collect())
Some(
self.data
.iter()
.filter(|todo| query.matches(*todo))
.collect(),
)
}

/// Update an item in the Store.
Expand Down Expand Up @@ -161,12 +167,10 @@ pub struct ItemList {
list: Vec<Item>,
}
impl ItemList {
fn into_iter(self) -> std::vec::IntoIter<Item> {
self.list.into_iter()
}
fn retain<F>(&mut self, f: F)
where
F: FnMut(&Item) -> bool {
F: FnMut(&Item) -> bool,
{
self.list.retain(f);
}
fn iter_mut(&mut self) -> std::slice::IterMut<Item> {
Expand Down
7 changes: 2 additions & 5 deletions examples/todomvc/src/template.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use store::{ItemList, ItemListTrait, Item};
use askama::Template as AskamaTemplate;
use store::{ItemList, ItemListTrait};

#[derive(AskamaTemplate)]
#[template(path = "row.html")]
Expand All @@ -9,7 +9,6 @@ struct RowTemplate<'a> {
completed: bool,
}


#[derive(AskamaTemplate)]
#[template(path = "itemsLeft.html")]
struct ItemsLeftTemplate {
Expand Down Expand Up @@ -46,9 +45,7 @@ impl Template {
///
/// Returns the contents for an "items left" indicator
pub fn item_counter(active_todos: usize) -> String {
let items_left = ItemsLeftTemplate {
active_todos
};
let items_left = ItemsLeftTemplate { active_todos };
if let Ok(res) = items_left.render() {
res
} else {
Expand Down
Loading

0 comments on commit 4a70198

Please sign in to comment.