Adding in is_dom_loaded function
This commit is contained in:
parent
ffdc651b08
commit
c422c61758
|
@ -15,6 +15,7 @@ stdweb-derive = "0.4.0"
|
|||
lazy_static = "1.0.0"
|
||||
discard = "1.0.3"
|
||||
futures-core = "0.2.0"
|
||||
futures-channel = "0.2.1"
|
||||
#futures-signals = { path = "../rust-signals" }
|
||||
futures-signals = { git = "https://github.com/Pauan/rust-signals" }
|
||||
|
||||
|
@ -29,6 +30,3 @@ debug-assertions = true
|
|||
|
||||
[profile.bench]
|
||||
debug-assertions = true
|
||||
|
||||
[features]
|
||||
debug-mode = []
|
||||
|
|
100
src/dom.rs
100
src/dom.rs
|
@ -1,5 +1,5 @@
|
|||
use std::ops::Deref;
|
||||
use stdweb::{Reference, Value, JsSerialize};
|
||||
use stdweb::{Reference, Value, JsSerialize, Once};
|
||||
use stdweb::unstable::{TryFrom, TryInto};
|
||||
use stdweb::web::{IEventTarget, INode, IElement, IHtmlElement, HtmlElement, Node, window, TextNode, EventTarget, Element};
|
||||
use stdweb::web::event::ConcreteEvent;
|
||||
|
@ -9,10 +9,12 @@ use operations;
|
|||
use operations::for_each;
|
||||
use dom_operations;
|
||||
use operations::{ValueDiscard, FnDiscard, spawn_future};
|
||||
use futures_signals::signal::IntoSignal;
|
||||
use futures_signals::signal::{IntoSignal, Signal};
|
||||
use futures_signals::signal_vec::IntoSignalVec;
|
||||
use futures_core::Never;
|
||||
use futures_core::{Never, Async};
|
||||
use futures_core::task::Context;
|
||||
use futures_core::future::Future;
|
||||
use futures_channel::oneshot;
|
||||
use discard::{Discard, DiscardOnDrop};
|
||||
|
||||
|
||||
|
@ -97,6 +99,94 @@ pub fn append_dom<A: INode>(parent: &A, mut dom: Dom) -> DomHandle {
|
|||
}
|
||||
|
||||
|
||||
struct IsDomLoadedEvent {
|
||||
callback: Value,
|
||||
}
|
||||
|
||||
impl IsDomLoadedEvent {
|
||||
#[inline]
|
||||
fn new<F>(callback: F) -> Self where F: FnOnce() + 'static {
|
||||
// TODO use a proper type for the event
|
||||
let callback = move |_: Value| {
|
||||
callback();
|
||||
};
|
||||
|
||||
Self {
|
||||
callback: js!(
|
||||
var callback = @{Once(callback)};
|
||||
document.addEventListener("DOMContentLoaded", callback, true);
|
||||
return callback;
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for IsDomLoadedEvent {
|
||||
fn drop(&mut self) {
|
||||
js! { @(no_return)
|
||||
var callback = @{&self.callback};
|
||||
document.removeEventListener("DOMContentLoaded", callback, true);
|
||||
callback.drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum IsDomLoaded {
|
||||
Initial {},
|
||||
Pending {
|
||||
receiver: oneshot::Receiver<()>,
|
||||
event: IsDomLoadedEvent,
|
||||
},
|
||||
Done {},
|
||||
}
|
||||
|
||||
impl Signal for IsDomLoaded {
|
||||
type Item = bool;
|
||||
|
||||
fn poll_change(&mut self, cx: &mut Context) -> Async<Option<Self::Item>> {
|
||||
let result = match self {
|
||||
IsDomLoaded::Initial {} => {
|
||||
let is_ready: bool = js!( return document.readyState !== "loading"; ).try_into().unwrap();
|
||||
|
||||
if is_ready {
|
||||
Async::Ready(Some(true))
|
||||
|
||||
} else {
|
||||
let (sender, receiver) = oneshot::channel();
|
||||
|
||||
*self = IsDomLoaded::Pending {
|
||||
receiver,
|
||||
event: IsDomLoadedEvent::new(move || {
|
||||
// TODO test this
|
||||
sender.send(()).unwrap();
|
||||
}),
|
||||
};
|
||||
|
||||
Async::Ready(Some(false))
|
||||
}
|
||||
},
|
||||
IsDomLoaded::Pending { receiver, .. } => {
|
||||
receiver.poll(cx).unwrap().map(|_| Some(true))
|
||||
},
|
||||
IsDomLoaded::Done {} => {
|
||||
Async::Ready(None)
|
||||
},
|
||||
};
|
||||
|
||||
if let Async::Ready(Some(true)) = result {
|
||||
*self = IsDomLoaded::Done {};
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_dom_loaded() -> impl Signal<Item = bool> {
|
||||
IsDomLoaded::Initial {}
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn text(value: &str) -> Dom {
|
||||
Dom::new(js!( return document.createTextNode(@{value}); ).try_into().unwrap())
|
||||
|
@ -516,10 +606,6 @@ impl<A: IElement + Clone + 'static> DomBuilder<A> {
|
|||
self.callbacks.after_insert(move |callbacks| {
|
||||
callbacks.after_remove(for_each(signal, move |value| {
|
||||
if let Some(value) = value {
|
||||
if cfg!(feature = "debug-mode") {
|
||||
console!(log, element.as_ref(), js!( return @{element.as_ref()}.parentNode; ), js!( return document.body.contains(@{element.as_ref()}); ), js!( return @{element.as_ref()}.clientHeight; ), js!( return [].slice.call(@{element.as_ref()}.childNodes).map(function (x) { return x.clientHeight; }) ));
|
||||
}
|
||||
|
||||
f(&element, value);
|
||||
}
|
||||
}));
|
||||
|
|
|
@ -12,6 +12,7 @@ extern crate lazy_static;
|
|||
|
||||
extern crate discard;
|
||||
extern crate futures_core;
|
||||
extern crate futures_channel;
|
||||
extern crate futures_signals;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue