Update yew-shared to 2018 edition

This commit is contained in:
Justin Starry 2019-06-28 22:38:50 -04:00
parent 0c5682d07c
commit b24dc28e20
18 changed files with 133 additions and 133 deletions

View File

@ -1,14 +1,17 @@
[package] [package]
name = "yew-shared" name = "yew-shared"
version = "0.7.0" version = "0.7.0"
edition = "2018"
[lib] [lib]
[dependencies] [dependencies]
log = "0.4" log = "0.4"
serde = "1.0" serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
bincode = "=1.0.1" bincode = "=1.0.1"
anymap = "0.12" anymap = "0.12"
slab = "0.4" slab = "0.4"
stdweb = "^0.4.14" stdweb = "^0.4.14"
[dev-dependencies]
yew = { path = "../.." }

View File

@ -1,15 +1,17 @@
//! This module contains types to support multi-threading in Yew. //! This module contains types to support multi-threading in Yew.
use std::rc::Rc; use crate::callback::Callback;
use crate::scheduler::{scheduler, Runnable, Shared};
use anymap::{AnyMap, Entry};
use bincode;
use log::warn;
use serde::{Deserialize, Serialize};
use slab::Slab;
use std::cell::RefCell; use std::cell::RefCell;
use std::marker::PhantomData; use std::marker::PhantomData;
use serde::{Serialize, Deserialize}; use std::rc::Rc;
use bincode;
use anymap::{AnyMap, Entry};
use slab::Slab;
use stdweb::Value; use stdweb::Value;
use scheduler::{Runnable, Shared, scheduler}; use stdweb::{_js_impl, js};
use callback::Callback;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
enum ToWorker<T> { enum ToWorker<T> {
@ -19,11 +21,7 @@ enum ToWorker<T> {
Destroy, Destroy,
} }
impl<T> Transferable for ToWorker<T> impl<T> Transferable for ToWorker<T> where T: Serialize + for<'de> Deserialize<'de> {}
where
T: Serialize + for <'de> Deserialize<'de>,
{
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
enum FromWorker<T> { enum FromWorker<T> {
@ -32,17 +30,12 @@ enum FromWorker<T> {
ProcessOutput(HandlerId, T), ProcessOutput(HandlerId, T),
} }
impl<T> Transferable for FromWorker<T> impl<T> Transferable for FromWorker<T> where T: Serialize + for<'de> Deserialize<'de> {}
where
T: Serialize + for <'de> Deserialize<'de>,
{
}
/// Represents a message which you could send to an agent. /// Represents a message which you could send to an agent.
pub trait Transferable pub trait Transferable
where where
Self: Serialize + for <'de> Deserialize<'de>, Self: Serialize + for<'de> Deserialize<'de>,
{ {
} }
@ -53,13 +46,11 @@ trait Packed {
impl<T: Transferable> Packed for T { impl<T: Transferable> Packed for T {
fn pack(&self) -> Vec<u8> { fn pack(&self) -> Vec<u8> {
bincode::serialize(&self) bincode::serialize(&self).expect("can't serialize a transferable object")
.expect("can't serialize a transferable object")
} }
fn unpack(data: &Vec<u8>) -> Self { fn unpack(data: &Vec<u8>) -> Self {
bincode::deserialize(&data) bincode::deserialize(&data).expect("can't deserialize a transferable object")
.expect("can't deserialize a transferable object")
} }
} }
@ -94,11 +85,11 @@ pub trait Threaded {
impl<T> Threaded for T impl<T> Threaded for T
where where
T: Agent<Reach=Public>, T: Agent<Reach = Public>,
{ {
fn register() { fn register() {
let scope = AgentScope::<T>::new(); let scope = AgentScope::<T>::new();
let responder = WorkerResponder { }; let responder = WorkerResponder {};
let link = AgentLink::connect(&scope, responder); let link = AgentLink::connect(&scope, responder);
let upd = AgentUpdate::Create(link); let upd = AgentUpdate::Create(link);
scope.send(upd); scope.send(upd);
@ -108,15 +99,15 @@ where
ToWorker::Connected(id) => { ToWorker::Connected(id) => {
let upd = AgentUpdate::Connected(id); let upd = AgentUpdate::Connected(id);
scope.send(upd); scope.send(upd);
}, }
ToWorker::ProcessInput(id, value) => { ToWorker::ProcessInput(id, value) => {
let upd = AgentUpdate::Input(value, id); let upd = AgentUpdate::Input(value, id);
scope.send(upd); scope.send(upd);
}, }
ToWorker::Disconnected(id) => { ToWorker::Disconnected(id) => {
let upd = AgentUpdate::Disconnected(id); let upd = AgentUpdate::Disconnected(id);
scope.send(upd); scope.send(upd);
}, }
ToWorker::Destroy => { ToWorker::Destroy => {
let upd = AgentUpdate::Destroy; let upd = AgentUpdate::Destroy;
scope.send(upd); scope.send(upd);
@ -124,7 +115,7 @@ where
// Terminates web worker // Terminates web worker
self.close(); self.close();
}; };
}, }
} }
}; };
let loaded: FromWorker<T::Output> = FromWorker::WorkerLoaded; let loaded: FromWorker<T::Output> = FromWorker::WorkerLoaded;
@ -215,14 +206,16 @@ impl Discoverer for Context {
Entry::Occupied(mut entry) => { Entry::Occupied(mut entry) => {
// TODO Insert callback! // TODO Insert callback!
entry.get_mut().create_bridge(callback) entry.get_mut().create_bridge(callback)
}, }
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let scope = AgentScope::<AGN>::new(); let scope = AgentScope::<AGN>::new();
let launched = LocalAgent::new(&scope); let launched = LocalAgent::new(&scope);
let responder = SlabResponder { slab: launched.slab() }; let responder = SlabResponder {
slab: launched.slab(),
};
scope_to_init = Some((scope.clone(), responder)); scope_to_init = Some((scope.clone(), responder));
entry.insert(launched).create_bridge(callback) entry.insert(launched).create_bridge(callback)
}, }
} }
}); });
if let Some((scope, responder)) = scope_to_init { if let Some((scope, responder)) = scope_to_init {
@ -346,11 +339,11 @@ impl Discoverer for Private {
match msg { match msg {
FromWorker::WorkerLoaded => { FromWorker::WorkerLoaded => {
// TODO Send `Connected` message // TODO Send `Connected` message
}, }
FromWorker::ProcessOutput(id, output) => { FromWorker::ProcessOutput(id, output) => {
assert_eq!(id.raw_id(), SINGLETON_ID.raw_id()); assert_eq!(id.raw_id(), SINGLETON_ID.raw_id());
callback.emit(output); callback.emit(output);
}, }
} }
}; };
// TODO Need somethig better... // TODO Need somethig better...
@ -441,7 +434,7 @@ impl Discoverer for Public {
Entry::Occupied(mut entry) => { Entry::Occupied(mut entry) => {
// TODO Insert callback! // TODO Insert callback!
entry.get_mut().create_bridge(callback) entry.get_mut().create_bridge(callback)
}, }
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let slab_base: Shared<Slab<Callback<AGN::Output>>> = let slab_base: Shared<Slab<Callback<AGN::Output>>> =
Rc::new(RefCell::new(Slab::new())); Rc::new(RefCell::new(Slab::new()));
@ -452,15 +445,18 @@ impl Discoverer for Public {
FromWorker::WorkerLoaded => { FromWorker::WorkerLoaded => {
// TODO Use `AtomicBool` lock to check its loaded // TODO Use `AtomicBool` lock to check its loaded
// TODO Send `Connected` message // TODO Send `Connected` message
}, }
FromWorker::ProcessOutput(id, output) => { FromWorker::ProcessOutput(id, output) => {
let callback = slab.borrow().get(id.raw_id()).cloned(); let callback = slab.borrow().get(id.raw_id()).cloned();
if let Some(callback) = callback { if let Some(callback) = callback {
callback.emit(output); callback.emit(output);
} else { } else {
warn!("Id of handler for remote worker not exists <slab>: {}", id.raw_id()); warn!(
"Id of handler for remote worker not exists <slab>: {}",
id.raw_id()
);
} }
}, }
} }
}; };
let name_of_resource = AGN::name_of_resource(); let name_of_resource = AGN::name_of_resource();
@ -474,7 +470,7 @@ impl Discoverer for Public {
}; };
let launched = RemoteAgent::new(&worker, slab_base); let launched = RemoteAgent::new(&worker, slab_base);
entry.insert(launched).create_bridge(callback) entry.insert(launched).create_bridge(callback)
}, }
} }
}); });
Box::new(bridge) Box::new(bridge)
@ -531,11 +527,10 @@ impl<AGN: Agent> Drop for PublicBridge<AGN> {
} }
} }
/// Create a single instance in a browser. /// Create a single instance in a browser.
pub struct Global; pub struct Global;
impl Discoverer for Global { } impl Discoverer for Global {}
/// Declares the behavior of the agent. /// Declares the behavior of the agent.
pub trait Agent: Sized + 'static { pub trait Agent: Sized + 'static {
@ -555,22 +550,22 @@ pub trait Agent: Sized + 'static {
fn update(&mut self, msg: Self::Message); fn update(&mut self, msg: Self::Message);
/// This method called on when a new bridge created. /// This method called on when a new bridge created.
fn connected(&mut self, _id: HandlerId) { } fn connected(&mut self, _id: HandlerId) {}
/// This method called on every incoming message. /// This method called on every incoming message.
fn handle(&mut self, msg: Self::Input, id: HandlerId); fn handle(&mut self, msg: Self::Input, id: HandlerId);
/// This method called on when a new bridge destroyed. /// This method called on when a new bridge destroyed.
fn disconnected(&mut self, _id: HandlerId) { } fn disconnected(&mut self, _id: HandlerId) {}
/// Creates an instance of an agent. /// Creates an instance of an agent.
fn destroy(&mut self) { } fn destroy(&mut self) {}
/// Represents the name of loading resorce for remote workers which /// Represents the name of loading resorce for remote workers which
/// have to live in a separate files. /// have to live in a separate files.
fn name_of_resource() -> &'static str { "main.js" } fn name_of_resource() -> &'static str {
"main.js"
}
} }
/// This sctruct holds a reference to a component and to a global scheduler. /// This sctruct holds a reference to a component and to a global scheduler.
@ -606,8 +601,7 @@ trait Responder<AGN: Agent> {
fn response(&self, id: HandlerId, output: AGN::Output); fn response(&self, id: HandlerId, output: AGN::Output);
} }
struct WorkerResponder { struct WorkerResponder {}
}
impl<AGN: Agent> Responder<AGN> for WorkerResponder { impl<AGN: Agent> Responder<AGN> for WorkerResponder {
fn response(&self, id: HandlerId, output: AGN::Output) { fn response(&self, id: HandlerId, output: AGN::Output) {
@ -702,27 +696,33 @@ where
this.agent = Some(AGN::create(env)); this.agent = Some(AGN::create(env));
} }
AgentUpdate::Message(msg) => { AgentUpdate::Message(msg) => {
this.agent.as_mut() this.agent
.as_mut()
.expect("agent was not created to process messages") .expect("agent was not created to process messages")
.update(msg); .update(msg);
} }
AgentUpdate::Connected(id) => { AgentUpdate::Connected(id) => {
this.agent.as_mut() this.agent
.as_mut()
.expect("agent was not created to send a connected message") .expect("agent was not created to send a connected message")
.connected(id); .connected(id);
} }
AgentUpdate::Input(inp, id) => { AgentUpdate::Input(inp, id) => {
this.agent.as_mut() this.agent
.as_mut()
.expect("agent was not created to process inputs") .expect("agent was not created to process inputs")
.handle(inp, id); .handle(inp, id);
} }
AgentUpdate::Disconnected(id) => { AgentUpdate::Disconnected(id) => {
this.agent.as_mut() this.agent
.as_mut()
.expect("agent was not created to send a disconnected message") .expect("agent was not created to send a disconnected message")
.disconnected(id); .disconnected(id);
} }
AgentUpdate::Destroy => { AgentUpdate::Destroy => {
let mut agent = this.agent.take() let mut agent = this
.agent
.take()
.expect("trying to destroy not existent agent"); .expect("trying to destroy not existent agent");
agent.destroy(); agent.destroy();
} }

View File

@ -1,8 +1,8 @@
//! This module contains `App` sctruct which used to bootstrap //! This module contains `App` sctruct which used to bootstrap
//! a component in an isolated scope. //! a component in an isolated scope.
use crate::html::{Component, Renderable, Scope};
use stdweb::web::{document, Element, INode, IParentNode}; use stdweb::web::{document, Element, INode, IParentNode};
use html::{Scope, Component, Renderable};
/// An application instance. /// An application instance.
pub struct App<COMP: Component> { pub struct App<COMP: Component> {
@ -46,4 +46,3 @@ fn clear_element(element: &Element) {
element.remove_child(&child).expect("can't remove a child"); element.remove_child(&child).expect("can't remove a child");
} }
} }

View File

@ -3,13 +3,15 @@
//! Also this module contains declaration of `Component` trait which used //! Also this module contains declaration of `Component` trait which used
//! to create own UI-components. //! to create own UI-components.
use std::rc::Rc; use crate::callback::Callback;
use crate::scheduler::{scheduler, Runnable, Shared};
use crate::virtual_dom::{Listener, VDiff, VNode};
use log::debug;
use std::cell::RefCell; use std::cell::RefCell;
use stdweb::web::{Element, EventListenerHandle, FileList, INode, Node}; use std::rc::Rc;
use stdweb::web::html_element::SelectElement; use stdweb::web::html_element::SelectElement;
use virtual_dom::{Listener, VDiff, VNode}; use stdweb::web::{Element, EventListenerHandle, FileList, INode, Node};
use callback::Callback; use stdweb::{_js_impl, js};
use scheduler::{Runnable, Shared, scheduler};
/// This type indicates that component should be rendered again. /// This type indicates that component should be rendered again.
pub type ShouldRender = bool; pub type ShouldRender = bool;
@ -33,7 +35,7 @@ pub trait Component: Sized + 'static {
unimplemented!("you should implement `change` method for a component with properties") unimplemented!("you should implement `change` method for a component with properties")
} }
/// Called for finalization on the final point of the component's lifetime. /// Called for finalization on the final point of the component's lifetime.
fn destroy(&mut self) { } // TODO Replace with `Drop` fn destroy(&mut self) {} // TODO Replace with `Drop`
} }
/// Should be rendered relative to context and component environment. /// Should be rendered relative to context and component environment.
@ -43,7 +45,7 @@ pub trait Renderable<COMP: Component> {
} }
/// Update message for a `Components` instance. Used by scope sender. /// Update message for a `Components` instance. Used by scope sender.
pub(crate) enum ComponentUpdate< COMP: Component> { pub(crate) enum ComponentUpdate<COMP: Component> {
/// Creating an instance of the component /// Creating an instance of the component
Create(ComponentLink<COMP>), Create(ComponentLink<COMP>),
/// Wraps messages for a component. /// Wraps messages for a component.
@ -195,7 +197,10 @@ where
return; return;
} }
let mut should_update = false; let mut should_update = false;
let upd = self.message.take().expect("component's envelope called twice"); let upd = self
.message
.take()
.expect("component's envelope called twice");
// This loop pops one item, because the following // This loop pops one item, because the following
// updates could try to borrow the same cell // updates could try to borrow the same cell
// Important! Don't use `while let` here, because it // Important! Don't use `while let` here, because it
@ -209,35 +214,44 @@ where
let current_frame = this.component.as_ref().unwrap().view(); let current_frame = this.component.as_ref().unwrap().view();
this.last_frame = Some(current_frame); this.last_frame = Some(current_frame);
// First-time rendering the tree // First-time rendering the tree
let node = this.last_frame.as_mut() let node = this.last_frame.as_mut().unwrap().apply(
.unwrap() this.element.as_node(),
.apply(this.element.as_node(), None, this.ancestor.take(), &env); None,
this.ancestor.take(),
&env,
);
if let Some(ref mut cell) = this.occupied { if let Some(ref mut cell) = this.occupied {
*cell.borrow_mut() = node; *cell.borrow_mut() = node;
} }
} }
ComponentUpdate::Message(msg) => { ComponentUpdate::Message(msg) => {
should_update |= this.component.as_mut() should_update |= this
.component
.as_mut()
.expect("component was not created to process messages") .expect("component was not created to process messages")
.update(msg); .update(msg);
} }
ComponentUpdate::Properties(props) => { ComponentUpdate::Properties(props) => {
should_update |= this.component.as_mut() should_update |= this
.component
.as_mut()
.expect("component was not created to process properties") .expect("component was not created to process properties")
.change(props); .change(props);
} }
ComponentUpdate::Destroy => { ComponentUpdate::Destroy => {
// TODO this.component.take() instead of destroyed // TODO this.component.take() instead of destroyed
this.component.as_mut().unwrap().destroy(); this.component.as_mut().unwrap().destroy();
this.last_frame.as_mut().unwrap().detach(this.element.as_node()); this.last_frame
.as_mut()
.unwrap()
.detach(this.element.as_node());
this.destroyed = true; this.destroyed = true;
} }
} }
if should_update { if should_update {
let mut next_frame = this.component.as_ref().unwrap().view(); let mut next_frame = this.component.as_ref().unwrap().view();
// Re-rendering the tree // Re-rendering the tree
let node = let node = next_frame.apply(this.element.as_node(), None, this.last_frame.take(), &env);
next_frame.apply(this.element.as_node(), None, this.last_frame.take(), &env);
if let Some(ref mut cell) = this.occupied { if let Some(ref mut cell) = this.occupied {
*cell.borrow_mut() = node; *cell.borrow_mut() = node;
} }

View File

@ -1,14 +1,3 @@
#[macro_use]
extern crate log;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate anymap;
extern crate bincode;
extern crate slab;
#[macro_use]
extern crate stdweb;
pub mod agent; pub mod agent;
pub mod app; pub mod app;
pub mod callback; pub mod callback;
@ -18,7 +7,7 @@ pub mod virtual_dom;
/// The module that contains all events available in the framework. /// The module that contains all events available in the framework.
pub mod events { pub mod events {
pub use html::{ChangeData, InputData}; pub use crate::html::{ChangeData, InputData};
pub use stdweb::web::event::{ pub use stdweb::web::event::{
BlurEvent, ClickEvent, ContextMenuEvent, DoubleClickEvent, DragDropEvent, DragEndEvent, BlurEvent, ClickEvent, ContextMenuEvent, DoubleClickEvent, DragDropEvent, DragEndEvent,
@ -33,19 +22,15 @@ pub mod events {
} }
pub mod prelude { pub mod prelude {
pub use html::{Component, ComponentLink, Href, Html, Renderable, ShouldRender}; pub use crate::agent::{Bridge, Bridged, Threaded};
pub use crate::app::App;
pub use app::App; pub use crate::callback::Callback;
pub use crate::events::*;
pub use callback::Callback; pub use crate::html::{Component, ComponentLink, Href, Html, Renderable, ShouldRender};
pub use agent::{Bridge, Bridged, Threaded};
pub use events::*;
/// Prelude module for creating worker. /// Prelude module for creating worker.
pub mod worker { pub mod worker {
pub use agent::{ pub use crate::agent::{
Agent, AgentLink, Bridge, Bridged, Context, Global, HandlerId, Job, Private, Public, Agent, AgentLink, Bridge, Bridged, Context, Global, HandlerId, Job, Private, Public,
Transferable, Transferable,
}; };

View File

@ -1,8 +1,8 @@
//! This module contains a scheduler. //! This module contains a scheduler.
use std::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::rc::Rc; use std::rc::Rc;
use std::cell::RefCell;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
pub(crate) type Shared<T> = Rc<RefCell<T>>; pub(crate) type Shared<T> = Rc<RefCell<T>>;

View File

@ -15,7 +15,7 @@ pub use self::vlist::VList;
pub use self::vnode::VNode; pub use self::vnode::VNode;
pub use self::vtag::VTag; pub use self::vtag::VTag;
pub use self::vtext::VText; pub use self::vtext::VText;
use html::{Component, Scope}; use crate::html::{Component, Scope};
/// `Listener` trait is an universal implementation of an event listener /// `Listener` trait is an universal implementation of an event listener
/// which helps to bind Rust-listener to JS-listener (DOM). /// which helps to bind Rust-listener to JS-listener (DOM).

View File

@ -1,14 +1,14 @@
//! This module contains the implementation of a virtual component `VComp`. //! This module contains the implementation of a virtual component `VComp`.
use super::{Reform, VDiff, VNode};
use crate::callback::Callback;
use crate::html::{Component, ComponentUpdate, NodeCell, Renderable, Scope};
use std::any::TypeId; use std::any::TypeId;
use std::cell::RefCell; use std::cell::RefCell;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use stdweb::unstable::TryInto; use stdweb::unstable::TryInto;
use stdweb::web::{document, Element, INode, Node}; use stdweb::web::{document, Element, INode, Node};
use html::{Component, ComponentUpdate, Scope, NodeCell, Renderable};
use callback::Callback;
use super::{Reform, VDiff, VNode};
struct Hidden; struct Hidden;
@ -79,7 +79,8 @@ impl<COMP: Component> VComp<COMP> {
// Ignore update till properties changed // Ignore update till properties changed
if previous_props != new_props { if previous_props != new_props {
let props = new_props.as_ref().unwrap().clone(); let props = new_props.as_ref().unwrap().clone();
lazy_activator.borrow_mut() lazy_activator
.borrow_mut()
.as_mut() .as_mut()
.expect("activator for child scope was not set (blind sender)") .expect("activator for child scope was not set (blind sender)")
.send(ComponentUpdate::Properties(props)); .send(ComponentUpdate::Properties(props));
@ -90,7 +91,8 @@ impl<COMP: Component> VComp<COMP> {
let destroyer = { let destroyer = {
let lazy_activator = lazy_activator; let lazy_activator = lazy_activator;
move || { move || {
lazy_activator.borrow_mut() lazy_activator
.borrow_mut()
.as_mut() .as_mut()
.expect("activator for child scope was not set (destroyer)") .expect("activator for child scope was not set (destroyer)")
.send(ComponentUpdate::Destroy); .send(ComponentUpdate::Destroy);
@ -229,7 +231,8 @@ where
fn detach(&mut self, parent: &Node) -> Option<Node> { fn detach(&mut self, parent: &Node) -> Option<Node> {
// Destroy the loop. It's impossible to use `Drop`, // Destroy the loop. It's impossible to use `Drop`,
// because parts can be reused with `grab_sender_of`. // because parts can be reused with `grab_sender_of`.
(self.destroyer)(); // TODO Chech it works (self.destroyer)(); // TODO Check it works
// Keep the sibling in the cell and send a message `Drop` to a loop // Keep the sibling in the cell and send a message `Drop` to a loop
self.cell.borrow_mut().take().and_then(|node| { self.cell.borrow_mut().take().and_then(|node| {
let sibling = node.next_sibling(); let sibling = node.next_sibling();

View File

@ -1,6 +1,6 @@
//! This module contains fragments implementation. //! This module contains fragments implementation.
use super::{VDiff, VNode, VText}; use super::{VDiff, VNode, VText};
use html::{Component, Scope}; use crate::html::{Component, Scope};
use stdweb::web::Node; use stdweb::web::Node;
/// This struct represents a fragment of the Virtual DOM tree. /// This struct represents a fragment of the Virtual DOM tree.

View File

@ -1,7 +1,7 @@
//! This module contains the implementation of abstract virtual node. //! This module contains the implementation of abstract virtual node.
use super::{VComp, VDiff, VList, VTag, VText}; use super::{VComp, VDiff, VList, VTag, VText};
use html::{Component, Renderable, Scope}; use crate::html::{Component, Renderable, Scope};
use std::cmp::PartialEq; use std::cmp::PartialEq;
use std::fmt; use std::fmt;
use stdweb::web::{INode, Node}; use stdweb::web::{INode, Node};

View File

@ -1,7 +1,8 @@
//! This module contains the implementation of a virtual element node `VTag`. //! This module contains the implementation of a virtual element node `VTag`.
use super::{Attributes, Classes, Listener, Listeners, Patch, Reform, VDiff, VNode}; use super::{Attributes, Classes, Listener, Listeners, Patch, Reform, VDiff, VNode};
use html::{Component, Scope}; use crate::html::{Component, Scope};
use log::warn;
use std::borrow::Cow; use std::borrow::Cow;
use std::cmp::PartialEq; use std::cmp::PartialEq;
use std::collections::HashSet; use std::collections::HashSet;
@ -10,6 +11,7 @@ use stdweb::unstable::TryFrom;
use stdweb::web::html_element::InputElement; use stdweb::web::html_element::InputElement;
use stdweb::web::html_element::TextAreaElement; use stdweb::web::html_element::TextAreaElement;
use stdweb::web::{document, Element, EventListenerHandle, IElement, INode, Node}; use stdweb::web::{document, Element, EventListenerHandle, IElement, INode, Node};
use stdweb::{_js_impl, js};
/// A type for a virtual /// A type for a virtual
/// [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element) /// [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element)

View File

@ -1,11 +1,12 @@
//! This module contains the implementation of a virtual text node `VText`. //! This module contains the implementation of a virtual text node `VText`.
use super::{Reform, VDiff, VNode};
use crate::html::{Component, Scope};
use log::warn;
use std::cmp::PartialEq; use std::cmp::PartialEq;
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use stdweb::web::{document, INode, Node, TextNode}; use stdweb::web::{document, INode, Node, TextNode};
use html::{Component, Scope};
use super::{Reform, VDiff, VNode};
/// A type for a virtual /// A type for a virtual
/// [`TextNode`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode) /// [`TextNode`](https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode)
@ -34,7 +35,9 @@ impl<COMP: Component> VDiff for VText<COMP> {
/// Remove VTag from parent. /// Remove VTag from parent.
fn detach(&mut self, parent: &Node) -> Option<Node> { fn detach(&mut self, parent: &Node) -> Option<Node> {
let node = self.reference.take() let node = self
.reference
.take()
.expect("tried to remove not rendered VText from DOM"); .expect("tried to remove not rendered VText from DOM");
let sibling = node.next_sibling(); let sibling = node.next_sibling();
if parent.remove_child(&node).is_err() { if parent.remove_child(&node).is_err() {
@ -54,7 +57,10 @@ impl<COMP: Component> VDiff for VText<COMP> {
opposite: Option<VNode<Self::Component>>, opposite: Option<VNode<Self::Component>>,
_: &Scope<Self::Component>, _: &Scope<Self::Component>,
) -> Option<Node> { ) -> Option<Node> {
assert!(self.reference.is_none(), "reference is ignored so must not be set"); assert!(
self.reference.is_none(),
"reference is ignored so must not be set"
);
let reform = { let reform = {
match opposite { match opposite {
// If element matched this type // If element matched this type

View File

@ -1,7 +1,5 @@
extern crate yew;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
use yew::virtual_dom::VNode; use yew::virtual_dom::VNode;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
struct Comp; struct Comp;

View File

@ -1,7 +1,5 @@
extern crate yew;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
use yew::virtual_dom::VNode; use yew::virtual_dom::VNode;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
struct Comp; struct Comp;

View File

@ -1,7 +1,5 @@
extern crate yew;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
use yew::virtual_dom::VNode; use yew::virtual_dom::VNode;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
struct Comp; struct Comp;

View File

@ -1,7 +1,5 @@
extern crate yew;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
use yew::virtual_dom::VNode; use yew::virtual_dom::VNode;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
struct Comp; struct Comp;
@ -30,4 +28,3 @@ fn text_as_root() {
{ "Text Node As Root" } { "Text Node As Root" }
}; };
} }

View File

@ -7,7 +7,6 @@ edition = "2018"
[dependencies] [dependencies]
log = "0.4" log = "0.4"
web_logger = "0.1" web_logger = "0.1"
serde = "1.0" serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
yew = { path = "../.." } yew = { path = "../.." }
stdweb = "0.4" stdweb = "0.4"

View File

@ -1,16 +1,14 @@
//! Agent that exposes a usable routing interface to components. //! Agent that exposes a usable routing interface to components.
use crate::routing::RouteService; use crate::routing::RouteService;
use yew::worker::*;
use log::info; use log::info;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use stdweb::Value;
use stdweb::JsSerialize;
use stdweb::unstable::TryFrom;
use serde::Serialize;
use serde::Deserialize;
use std::fmt::Debug; use std::fmt::Debug;
use stdweb::JsSerialize;
use stdweb::Value;
use stdweb::unstable::TryFrom;
use yew::worker::*;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize) ] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize) ]
pub struct Route<T> { pub struct Route<T> {