Adding in scroll_left_signal and scroll_top_signal

This commit is contained in:
Pauan 2018-07-03 17:44:50 -10:00
parent ee33a8335b
commit 6fcff5c63d
5 changed files with 64 additions and 35 deletions

View File

@ -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;
}
}

View File

@ -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> {

View File

@ -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 = "";
}

View File

@ -1,4 +1,5 @@
#![recursion_limit="128"]
#![warn(unreachable_pub)]
#[macro_use]
extern crate stdweb;

View File

@ -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 {