diff --git a/src/callbacks.rs b/src/callbacks.rs index cf43d3d..8fd97bf 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -28,10 +28,10 @@ impl IRemove for A { } -pub struct InsertCallback(Box); +pub(crate) struct InsertCallback(Box); // TODO is there a more efficient way of doing this ? -pub struct RemoveCallback(Box); +pub(crate) struct RemoveCallback(Box); 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, - pub after_remove: Vec, +pub(crate) struct Callbacks { + pub(crate) after_insert: Vec, + pub(crate) after_remove: Vec, 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(&mut self, callback: A) { + pub(crate) fn after_insert(&mut self, callback: A) { self.after_insert.push(InsertCallback(Box::new(callback))); } #[inline] - pub fn after_remove(&mut self, value: A) { + pub(crate) fn after_remove(&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; } } diff --git a/src/dom.rs b/src/dom.rs index f447174..fe41afb 100644 --- a/src/dom.rs +++ b/src/dom.rs @@ -500,6 +500,34 @@ impl DomBuilder { self.set_class_signal(name, value); self } + + // TODO generalize IntoOptionStr ? + #[inline] + pub fn scroll_left_signal(mut self, signal: B) -> Self where B: IntoSignal>, 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(mut self, signal: B) -> Self where B: IntoSignal>, 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 DomBuilder { diff --git a/src/dom_operations.rs b/src/dom_operations.rs index 5aa69c5..36ab6e4 100644 --- a/src/dom_operations.rs +++ b/src/dom_operations.rs @@ -5,14 +5,14 @@ use stdweb::web::{TextNode, INode, IHtmlElement, IElement}; #[inline] -pub fn create_element_ns(name: &str, namespace: &str) -> A +pub(crate) fn create_element_ns(name: &str, namespace: &str) -> A where >::Error: std::fmt::Debug { js!( return document.createElementNS(@{namespace}, @{name}); ).try_into().unwrap() } // TODO make this more efficient #[inline] -pub fn move_from_to(parent: &A, old_index: u32, new_index: u32) { +pub(crate) fn move_from_to(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(parent: &A, old_index: u32, new_index: u32) { // TODO make this more efficient #[inline] -pub fn insert_at(parent: &A, index: u32, child: &B) { +pub(crate) fn insert_at(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(parent: &A, index: u32, child: &B) { // TODO make this more efficient #[inline] -pub fn update_at(parent: &A, index: u32, child: &B) { +pub(crate) fn update_at(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(parent: &A, index: u32, child: &B) { // TODO make this more efficient #[inline] -pub fn remove_at(parent: &A, index: u32) { +pub(crate) fn remove_at(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(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>(element: &A, name: &str, value: &str, impo // TODO this should be in stdweb // TODO maybe use cfg(debug_assertions) ? -pub fn try_set_style>(element: &A, name: &str, value: &str, important: bool) -> bool { +pub(crate) fn try_set_style>(element: &A, name: &str, value: &str, important: bool) -> bool { assert!(value != ""); remove_style(element, name); @@ -85,7 +85,7 @@ pub fn try_set_style>(element: &A, name: &str, value: &str, // TODO this should be in stdweb // TODO handle browser prefixes #[inline] -pub fn remove_style>(element: &A, name: &str) { +pub(crate) fn remove_style>(element: &A, name: &str) { js! { @(no_return) @{element.as_ref()}.style.removeProperty(@{name}); } @@ -94,7 +94,7 @@ pub fn remove_style>(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(element: &A, focused: bool) { +pub(crate) fn set_focused(element: &A, focused: bool) { js! { @(no_return) var element = @{element.as_ref()}; @@ -108,14 +108,14 @@ pub fn set_focused(element: &A, focused: bool) { } #[inline] -pub fn add_class(element: &A, name: &str) { +pub(crate) fn add_class(element: &A, name: &str) { js! { @(no_return) @{element.as_ref()}.classList.add(@{name}); } } #[inline] -pub fn remove_class(element: &A, name: &str) { +pub(crate) fn remove_class(element: &A, name: &str) { js! { @(no_return) @{element.as_ref()}.classList.remove(@{name}); } @@ -124,7 +124,7 @@ pub fn remove_class(element: &A, name: &str) { // TODO check that the attribute *actually* was changed #[inline] -pub fn set_attribute(element: &A, name: &str, value: &str) { +pub(crate) fn set_attribute(element: &A, name: &str, value: &str) { js! { @(no_return) @{element.as_ref()}.setAttribute(@{name}, @{value}); } @@ -132,7 +132,7 @@ pub fn set_attribute(element: &A, name: &str, value: &str) { // TODO check that the attribute *actually* was changed #[inline] -pub fn set_attribute_ns(element: &A, namespace: &str, name: &str, value: &str) { +pub(crate) fn set_attribute_ns(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(element: &A, namespace: &str, name: &str, v #[inline] -pub fn remove_attribute_ns(element: &A, namespace: &str, name: &str) { +pub(crate) fn remove_attribute_ns(element: &A, namespace: &str, name: &str) { js! { @(no_return) @{element.as_ref()}.removeAttributeNS(@{namespace}, @{name}); } } #[inline] -pub fn remove_attribute(element: &A, name: &str) { +pub(crate) fn remove_attribute(element: &A, name: &str) { js! { @(no_return) @{element.as_ref()}.removeAttribute(@{name}); } @@ -157,7 +157,7 @@ pub fn remove_attribute(element: &A, name: &str) { // TODO check that the property *actually* was changed ? // TODO better type checks ? #[inline] -pub fn set_property, B: JsSerialize>(obj: &A, name: &str, value: B) { +pub(crate) fn set_property, B: JsSerialize>(obj: &A, name: &str, value: B) { js! { @(no_return) @{obj.as_ref()}[@{name}] = @{value}; } @@ -167,7 +167,7 @@ pub fn set_property, 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(element: &A) { +pub(crate) fn remove_all_children(element: &A) { js! { @(no_return) @{element.as_ref()}.innerHTML = ""; } diff --git a/src/lib.rs b/src/lib.rs index acc8a56..598865d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![recursion_limit="128"] +#![warn(unreachable_pub)] #[macro_use] extern crate stdweb; diff --git a/src/operations.rs b/src/operations.rs index 43aba49..76d954e 100644 --- a/src/operations.rs +++ b/src/operations.rs @@ -16,7 +16,7 @@ use futures_core::future::Future; // TODO this should probably be in stdweb #[inline] -pub fn spawn_future(future: F) -> DiscardOnDrop +pub(crate) fn spawn_future(future: F) -> DiscardOnDrop where F: Future + 'static { // TODO make this more efficient ? let (handle, future) = cancelable_future(future, |_| ()); @@ -28,7 +28,7 @@ pub fn spawn_future(future: F) -> DiscardOnDrop #[inline] -pub fn for_each(signal: A, mut callback: B) -> CancelableFutureHandle +pub(crate) fn for_each(signal: A, mut callback: B) -> CancelableFutureHandle where A: Signal + 'static, B: FnMut(A::Item) + 'static { @@ -80,7 +80,7 @@ pub fn insert_children_signal(element: &A, callbacks: &mut Callbacks, s }*/ #[inline] -pub fn insert_children_iter<'a, A: INode, B: IntoIterator>(element: &A, callbacks: &mut Callbacks, value: B) { +pub(crate) fn insert_children_iter<'a, A: INode, B: IntoIterator>(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>(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(ManuallyDrop); +pub(crate) struct ValueDiscard(ManuallyDrop); impl ValueDiscard { #[inline] - pub fn new(value: A) -> Self { + pub(crate) fn new(value: A) -> Self { ValueDiscard(ManuallyDrop::new(value)) } } @@ -112,11 +112,11 @@ impl Discard for ValueDiscard { // TODO move this into the discard crate // TODO replace this with an impl for FnOnce() ? -pub struct FnDiscard(A); +pub(crate) struct FnDiscard(A); impl FnDiscard where A: FnOnce() { #[inline] - pub fn new(f: A) -> Self { + pub(crate) fn new(f: A) -> Self { FnDiscard(f) } } @@ -129,7 +129,7 @@ impl Discard for FnDiscard where A: FnOnce() { } -pub fn insert_children_signal_vec(element: &A, callbacks: &mut Callbacks, signal: B) +pub(crate) fn insert_children_signal_vec(element: &A, callbacks: &mut Callbacks, signal: B) where A: INode + Clone + 'static, B: IntoSignalVec, B::SignalVec: 'static {