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"
|
lazy_static = "1.0.0"
|
||||||
discard = "1.0.3"
|
discard = "1.0.3"
|
||||||
futures-core = "0.2.0"
|
futures-core = "0.2.0"
|
||||||
|
futures-channel = "0.2.1"
|
||||||
#futures-signals = { path = "../rust-signals" }
|
#futures-signals = { path = "../rust-signals" }
|
||||||
futures-signals = { git = "https://github.com/Pauan/rust-signals" }
|
futures-signals = { git = "https://github.com/Pauan/rust-signals" }
|
||||||
|
|
||||||
|
@ -29,6 +30,3 @@ debug-assertions = true
|
||||||
|
|
||||||
[profile.bench]
|
[profile.bench]
|
||||||
debug-assertions = true
|
debug-assertions = true
|
||||||
|
|
||||||
[features]
|
|
||||||
debug-mode = []
|
|
||||||
|
|
100
src/dom.rs
100
src/dom.rs
|
@ -1,5 +1,5 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use stdweb::{Reference, Value, JsSerialize};
|
use stdweb::{Reference, Value, JsSerialize, Once};
|
||||||
use stdweb::unstable::{TryFrom, TryInto};
|
use stdweb::unstable::{TryFrom, TryInto};
|
||||||
use stdweb::web::{IEventTarget, INode, IElement, IHtmlElement, HtmlElement, Node, window, TextNode, EventTarget, Element};
|
use stdweb::web::{IEventTarget, INode, IElement, IHtmlElement, HtmlElement, Node, window, TextNode, EventTarget, Element};
|
||||||
use stdweb::web::event::ConcreteEvent;
|
use stdweb::web::event::ConcreteEvent;
|
||||||
|
@ -9,10 +9,12 @@ use operations;
|
||||||
use operations::for_each;
|
use operations::for_each;
|
||||||
use dom_operations;
|
use dom_operations;
|
||||||
use operations::{ValueDiscard, FnDiscard, spawn_future};
|
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_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_core::future::Future;
|
||||||
|
use futures_channel::oneshot;
|
||||||
use discard::{Discard, DiscardOnDrop};
|
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]
|
#[inline]
|
||||||
pub fn text(value: &str) -> Dom {
|
pub fn text(value: &str) -> Dom {
|
||||||
Dom::new(js!( return document.createTextNode(@{value}); ).try_into().unwrap())
|
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| {
|
self.callbacks.after_insert(move |callbacks| {
|
||||||
callbacks.after_remove(for_each(signal, move |value| {
|
callbacks.after_remove(for_each(signal, move |value| {
|
||||||
if let Some(value) = 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);
|
f(&element, value);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -12,6 +12,7 @@ extern crate lazy_static;
|
||||||
|
|
||||||
extern crate discard;
|
extern crate discard;
|
||||||
extern crate futures_core;
|
extern crate futures_core;
|
||||||
|
extern crate futures_channel;
|
||||||
extern crate futures_signals;
|
extern crate futures_signals;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue