Adding in scroll_left_signal and scroll_top_signal
This commit is contained in:
parent
ee33a8335b
commit
6fcff5c63d
|
@ -28,10 +28,10 @@ impl<A: Discard> IRemove for A {
|
|||
}
|
||||
|
||||
|
||||
pub struct InsertCallback(Box<IInsertCallback>);
|
||||
pub(crate) struct InsertCallback(Box<IInsertCallback>);
|
||||
|
||||
// TODO is there a more efficient way of doing this ?
|
||||
pub struct RemoveCallback(Box<IRemove>);
|
||||
pub(crate) struct RemoveCallback(Box<IRemove>);
|
||||
|
||||
impl std::fmt::Debug for InsertCallback {
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
|
@ -47,15 +47,15 @@ impl std::fmt::Debug for RemoveCallback {
|
|||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Callbacks {
|
||||
pub after_insert: Vec<InsertCallback>,
|
||||
pub after_remove: Vec<RemoveCallback>,
|
||||
pub(crate) struct Callbacks {
|
||||
pub(crate) after_insert: Vec<InsertCallback>,
|
||||
pub(crate) after_remove: Vec<RemoveCallback>,
|
||||
trigger_remove: bool,
|
||||
}
|
||||
|
||||
impl Callbacks {
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
after_insert: vec![],
|
||||
after_remove: vec![],
|
||||
|
@ -64,18 +64,18 @@ impl Callbacks {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn after_insert<A: FnOnce(&mut Callbacks) + 'static>(&mut self, callback: A) {
|
||||
pub(crate) fn after_insert<A: FnOnce(&mut Callbacks) + 'static>(&mut self, callback: A) {
|
||||
self.after_insert.push(InsertCallback(Box::new(callback)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn after_remove<A: Discard + 'static>(&mut self, value: A) {
|
||||
pub(crate) fn after_remove<A: Discard + 'static>(&mut self, value: A) {
|
||||
self.after_remove.push(RemoveCallback(Box::new(value)));
|
||||
}
|
||||
|
||||
// TODO runtime checks to make sure this isn't called multiple times ?
|
||||
#[inline]
|
||||
pub fn trigger_after_insert(&mut self) {
|
||||
pub(crate) fn trigger_after_insert(&mut self) {
|
||||
let mut callbacks = Callbacks::new();
|
||||
|
||||
// TODO verify that this is correct
|
||||
|
@ -105,7 +105,7 @@ impl Callbacks {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn leak(&mut self) {
|
||||
pub(crate) fn leak(&mut self) {
|
||||
self.trigger_remove = false;
|
||||
}
|
||||
}
|
||||
|
|
28
src/dom.rs
28
src/dom.rs
|
@ -500,6 +500,34 @@ impl<A: IElement + Clone + 'static> DomBuilder<A> {
|
|||
self.set_class_signal(name, value);
|
||||
self
|
||||
}
|
||||
|
||||
// TODO generalize IntoOptionStr ?
|
||||
#[inline]
|
||||
pub fn scroll_left_signal<B>(mut self, signal: B) -> Self where B: IntoSignal<Item = Option<f64>>, B::Signal: 'static {
|
||||
let element = self.element.clone();
|
||||
|
||||
self.callbacks.after_remove(for_each(signal.into_signal(), move |value| {
|
||||
if let Some(value) = value {
|
||||
element.set_scroll_left(value);
|
||||
}
|
||||
}));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
// TODO generalize IntoOptionStr ?
|
||||
#[inline]
|
||||
pub fn scroll_top_signal<B>(mut self, signal: B) -> Self where B: IntoSignal<Item = Option<f64>>, B::Signal: 'static {
|
||||
let element = self.element.clone();
|
||||
|
||||
self.callbacks.after_remove(for_each(signal.into_signal(), move |value| {
|
||||
if let Some(value) = value {
|
||||
element.set_scroll_top(value);
|
||||
}
|
||||
}));
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: IHtmlElement> DomBuilder<A> {
|
||||
|
|
|
@ -5,14 +5,14 @@ use stdweb::web::{TextNode, INode, IHtmlElement, IElement};
|
|||
|
||||
|
||||
#[inline]
|
||||
pub fn create_element_ns<A: IElement>(name: &str, namespace: &str) -> A
|
||||
pub(crate) fn create_element_ns<A: IElement>(name: &str, namespace: &str) -> A
|
||||
where <A as TryFrom<Value>>::Error: std::fmt::Debug {
|
||||
js!( return document.createElementNS(@{namespace}, @{name}); ).try_into().unwrap()
|
||||
}
|
||||
|
||||
// TODO make this more efficient
|
||||
#[inline]
|
||||
pub fn move_from_to<A: INode>(parent: &A, old_index: u32, new_index: u32) {
|
||||
pub(crate) fn move_from_to<A: INode>(parent: &A, old_index: u32, new_index: u32) {
|
||||
js! { @(no_return)
|
||||
var parent = @{parent.as_ref()};
|
||||
// TODO verify that it exists ?
|
||||
|
@ -24,7 +24,7 @@ pub fn move_from_to<A: INode>(parent: &A, old_index: u32, new_index: u32) {
|
|||
|
||||
// TODO make this more efficient
|
||||
#[inline]
|
||||
pub fn insert_at<A: INode, B: INode>(parent: &A, index: u32, child: &B) {
|
||||
pub(crate) fn insert_at<A: INode, B: INode>(parent: &A, index: u32, child: &B) {
|
||||
js! { @(no_return)
|
||||
var parent = @{parent.as_ref()};
|
||||
parent.insertBefore(@{child.as_ref()}, parent.childNodes[@{index}]);
|
||||
|
@ -33,7 +33,7 @@ pub fn insert_at<A: INode, B: INode>(parent: &A, index: u32, child: &B) {
|
|||
|
||||
// TODO make this more efficient
|
||||
#[inline]
|
||||
pub fn update_at<A: INode, B: INode>(parent: &A, index: u32, child: &B) {
|
||||
pub(crate) fn update_at<A: INode, B: INode>(parent: &A, index: u32, child: &B) {
|
||||
js! { @(no_return)
|
||||
var parent = @{parent.as_ref()};
|
||||
parent.replaceChild(@{child.as_ref()}, parent.childNodes[@{index}]);
|
||||
|
@ -42,7 +42,7 @@ pub fn update_at<A: INode, B: INode>(parent: &A, index: u32, child: &B) {
|
|||
|
||||
// TODO make this more efficient
|
||||
#[inline]
|
||||
pub fn remove_at<A: INode>(parent: &A, index: u32) {
|
||||
pub(crate) fn remove_at<A: INode>(parent: &A, index: u32) {
|
||||
js! { @(no_return)
|
||||
var parent = @{parent.as_ref()};
|
||||
parent.removeChild(parent.childNodes[@{index}]);
|
||||
|
@ -51,7 +51,7 @@ pub fn remove_at<A: INode>(parent: &A, index: u32) {
|
|||
|
||||
// TODO this should be in stdweb
|
||||
#[inline]
|
||||
pub fn set_text(element: &TextNode, value: &str) {
|
||||
pub(crate) fn set_text(element: &TextNode, value: &str) {
|
||||
js! { @(no_return)
|
||||
// http://jsperf.com/textnode-performance
|
||||
@{element}.data = @{value};
|
||||
|
@ -73,7 +73,7 @@ fn set_style_raw<A: AsRef<Reference>>(element: &A, name: &str, value: &str, impo
|
|||
|
||||
// TODO this should be in stdweb
|
||||
// TODO maybe use cfg(debug_assertions) ?
|
||||
pub fn try_set_style<A: AsRef<Reference>>(element: &A, name: &str, value: &str, important: bool) -> bool {
|
||||
pub(crate) fn try_set_style<A: AsRef<Reference>>(element: &A, name: &str, value: &str, important: bool) -> bool {
|
||||
assert!(value != "");
|
||||
|
||||
remove_style(element, name);
|
||||
|
@ -85,7 +85,7 @@ pub fn try_set_style<A: AsRef<Reference>>(element: &A, name: &str, value: &str,
|
|||
// TODO this should be in stdweb
|
||||
// TODO handle browser prefixes
|
||||
#[inline]
|
||||
pub fn remove_style<A: AsRef<Reference>>(element: &A, name: &str) {
|
||||
pub(crate) fn remove_style<A: AsRef<Reference>>(element: &A, name: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.style.removeProperty(@{name});
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ pub fn remove_style<A: AsRef<Reference>>(element: &A, name: &str) {
|
|||
// TODO replace with element.focus() and element.blur()
|
||||
// TODO make element.focus() and element.blur() inline
|
||||
#[inline]
|
||||
pub fn set_focused<A: IHtmlElement>(element: &A, focused: bool) {
|
||||
pub(crate) fn set_focused<A: IHtmlElement>(element: &A, focused: bool) {
|
||||
js! { @(no_return)
|
||||
var element = @{element.as_ref()};
|
||||
|
||||
|
@ -108,14 +108,14 @@ pub fn set_focused<A: IHtmlElement>(element: &A, focused: bool) {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn add_class<A: IElement>(element: &A, name: &str) {
|
||||
pub(crate) fn add_class<A: IElement>(element: &A, name: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.classList.add(@{name});
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn remove_class<A: IElement>(element: &A, name: &str) {
|
||||
pub(crate) fn remove_class<A: IElement>(element: &A, name: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.classList.remove(@{name});
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ pub fn remove_class<A: IElement>(element: &A, name: &str) {
|
|||
|
||||
// TODO check that the attribute *actually* was changed
|
||||
#[inline]
|
||||
pub fn set_attribute<A: IElement>(element: &A, name: &str, value: &str) {
|
||||
pub(crate) fn set_attribute<A: IElement>(element: &A, name: &str, value: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.setAttribute(@{name}, @{value});
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ pub fn set_attribute<A: IElement>(element: &A, name: &str, value: &str) {
|
|||
|
||||
// TODO check that the attribute *actually* was changed
|
||||
#[inline]
|
||||
pub fn set_attribute_ns<A: IElement>(element: &A, namespace: &str, name: &str, value: &str) {
|
||||
pub(crate) fn set_attribute_ns<A: IElement>(element: &A, namespace: &str, name: &str, value: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.setAttributeNS(@{namespace}, @{name}, @{value});
|
||||
}
|
||||
|
@ -140,14 +140,14 @@ pub fn set_attribute_ns<A: IElement>(element: &A, namespace: &str, name: &str, v
|
|||
|
||||
|
||||
#[inline]
|
||||
pub fn remove_attribute_ns<A: IElement>(element: &A, namespace: &str, name: &str) {
|
||||
pub(crate) fn remove_attribute_ns<A: IElement>(element: &A, namespace: &str, name: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.removeAttributeNS(@{namespace}, @{name});
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn remove_attribute<A: IElement>(element: &A, name: &str) {
|
||||
pub(crate) fn remove_attribute<A: IElement>(element: &A, name: &str) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.removeAttribute(@{name});
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ pub fn remove_attribute<A: IElement>(element: &A, name: &str) {
|
|||
// TODO check that the property *actually* was changed ?
|
||||
// TODO better type checks ?
|
||||
#[inline]
|
||||
pub fn set_property<A: AsRef<Reference>, B: JsSerialize>(obj: &A, name: &str, value: B) {
|
||||
pub(crate) fn set_property<A: AsRef<Reference>, B: JsSerialize>(obj: &A, name: &str, value: B) {
|
||||
js! { @(no_return)
|
||||
@{obj.as_ref()}[@{name}] = @{value};
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ pub fn set_property<A: AsRef<Reference>, B: JsSerialize>(obj: &A, name: &str, va
|
|||
// TODO make this work on Nodes, not just Elements
|
||||
// TODO is this the most efficient way to remove all children ?
|
||||
#[inline]
|
||||
pub fn remove_all_children<A: INode>(element: &A) {
|
||||
pub(crate) fn remove_all_children<A: INode>(element: &A) {
|
||||
js! { @(no_return)
|
||||
@{element.as_ref()}.innerHTML = "";
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#![recursion_limit="128"]
|
||||
#![warn(unreachable_pub)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate stdweb;
|
||||
|
|
|
@ -16,7 +16,7 @@ use futures_core::future::Future;
|
|||
|
||||
// TODO this should probably be in stdweb
|
||||
#[inline]
|
||||
pub fn spawn_future<F>(future: F) -> DiscardOnDrop<CancelableFutureHandle>
|
||||
pub(crate) fn spawn_future<F>(future: F) -> DiscardOnDrop<CancelableFutureHandle>
|
||||
where F: Future<Item = (), Error = Never> + 'static {
|
||||
// TODO make this more efficient ?
|
||||
let (handle, future) = cancelable_future(future, |_| ());
|
||||
|
@ -28,7 +28,7 @@ pub fn spawn_future<F>(future: F) -> DiscardOnDrop<CancelableFutureHandle>
|
|||
|
||||
|
||||
#[inline]
|
||||
pub fn for_each<A, B>(signal: A, mut callback: B) -> CancelableFutureHandle
|
||||
pub(crate) fn for_each<A, B>(signal: A, mut callback: B) -> CancelableFutureHandle
|
||||
where A: Signal + 'static,
|
||||
B: FnMut(A::Item) + 'static {
|
||||
|
||||
|
@ -80,7 +80,7 @@ pub fn insert_children_signal<A, B, C>(element: &A, callbacks: &mut Callbacks, s
|
|||
}*/
|
||||
|
||||
#[inline]
|
||||
pub fn insert_children_iter<'a, A: INode, B: IntoIterator<Item = &'a mut Dom>>(element: &A, callbacks: &mut Callbacks, value: B) {
|
||||
pub(crate) fn insert_children_iter<'a, A: INode, B: IntoIterator<Item = &'a mut Dom>>(element: &A, callbacks: &mut Callbacks, value: B) {
|
||||
for dom in value.into_iter() {
|
||||
callbacks.after_insert.append(&mut dom.callbacks.after_insert);
|
||||
callbacks.after_remove.append(&mut dom.callbacks.after_remove);
|
||||
|
@ -92,11 +92,11 @@ pub fn insert_children_iter<'a, A: INode, B: IntoIterator<Item = &'a mut Dom>>(e
|
|||
|
||||
// TODO move this into the discard crate
|
||||
// TODO verify that this is correct and doesn't leak memory or cause memory safety
|
||||
pub struct ValueDiscard<A>(ManuallyDrop<A>);
|
||||
pub(crate) struct ValueDiscard<A>(ManuallyDrop<A>);
|
||||
|
||||
impl<A> ValueDiscard<A> {
|
||||
#[inline]
|
||||
pub fn new(value: A) -> Self {
|
||||
pub(crate) fn new(value: A) -> Self {
|
||||
ValueDiscard(ManuallyDrop::new(value))
|
||||
}
|
||||
}
|
||||
|
@ -112,11 +112,11 @@ impl<A> Discard for ValueDiscard<A> {
|
|||
|
||||
// TODO move this into the discard crate
|
||||
// TODO replace this with an impl for FnOnce() ?
|
||||
pub struct FnDiscard<A>(A);
|
||||
pub(crate) struct FnDiscard<A>(A);
|
||||
|
||||
impl<A> FnDiscard<A> where A: FnOnce() {
|
||||
#[inline]
|
||||
pub fn new(f: A) -> Self {
|
||||
pub(crate) fn new(f: A) -> Self {
|
||||
FnDiscard(f)
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ impl<A> Discard for FnDiscard<A> where A: FnOnce() {
|
|||
}
|
||||
|
||||
|
||||
pub fn insert_children_signal_vec<A, B>(element: &A, callbacks: &mut Callbacks, signal: B)
|
||||
pub(crate) fn insert_children_signal_vec<A, B>(element: &A, callbacks: &mut Callbacks, signal: B)
|
||||
where A: INode + Clone + 'static,
|
||||
B: IntoSignalVec<Item = Dom>,
|
||||
B::SignalVec: 'static {
|
||||
|
|
Loading…
Reference in New Issue