Adding in support for setting multiple style names

This commit is contained in:
Pauan 2018-06-28 07:02:35 -10:00
parent c119d1b2ed
commit ee33a8335b
3 changed files with 128 additions and 91 deletions

View File

@ -504,49 +504,50 @@ impl<A: IElement + Clone + 'static> DomBuilder<A> {
impl<A: IHtmlElement> DomBuilder<A> {
#[inline]
pub fn style(self, name: &str, value: &str) -> Self {
dom_operations::set_style(&self.element, name, value, false);
pub fn style<B: StyleName>(self, name: B, value: &str) -> Self {
name.set_style(&self.element, value, false);
self
}
#[inline]
pub fn style_important(self, name: &str, value: &str) -> Self {
dom_operations::set_style(&self.element, name, value, true);
pub fn style_important<B: StyleName>(self, name: B, value: &str) -> Self {
name.set_style(&self.element, value, true);
self
}
}
impl<A: IHtmlElement + Clone + 'static> DomBuilder<A> {
fn set_style_signal<B, C>(&mut self, name: &str, value: C, important: bool)
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
let name = name.to_owned();
fn set_style_signal<B, C, D>(&mut self, name: B, value: D, important: bool)
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
set_option_str(&self.element, &mut self.callbacks, value, move |element, value| {
match value {
Some(value) => dom_operations::set_style(element, &name, value, important),
None => dom_operations::remove_style(element, &name),
Some(value) => name.set_style(element, value, important),
None => name.remove_style(element),
}
});
}
#[inline]
pub fn style_signal<B, C>(mut self, name: &str, value: C) -> Self
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
pub fn style_signal<B, C, D>(mut self, name: B, value: D) -> Self
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
self.set_style_signal(name, value, false);
self
}
#[inline]
pub fn style_important_signal<B, C>(mut self, name: &str, value: C) -> Self
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
pub fn style_important_signal<B, C, D>(mut self, name: B, value: D) -> Self
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
self.set_style_signal(name, value, true);
self
@ -627,48 +628,49 @@ impl StylesheetBuilder {
}
#[inline]
pub fn style(self, name: &str, value: &str) -> Self {
dom_operations::set_style(&self.element, name, value, false);
pub fn style<B: StyleName>(self, name: B, value: &str) -> Self {
name.set_style(&self.element, value, false);
self
}
#[inline]
pub fn style_important(self, name: &str, value: &str) -> Self {
dom_operations::set_style(&self.element, name, value, true);
pub fn style_important<B: StyleName>(self, name: B, value: &str) -> Self {
name.set_style(&self.element, value, true);
self
}
fn set_style_signal<B, C>(&mut self, name: &str, value: C, important: bool)
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
let name = name.to_owned();
fn set_style_signal<B, C, D>(&mut self, name: B, value: D, important: bool)
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
set_option_str(&self.element, &mut self.callbacks, value, move |element, value| {
match value {
Some(value) => dom_operations::set_style(element, &name, value, important),
None => dom_operations::remove_style(element, &name),
Some(value) => name.set_style(element, value, important),
None => name.remove_style(element),
}
});
}
#[inline]
pub fn style_signal<B, C>(mut self, name: &str, value: C) -> Self
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
pub fn style_signal<B, C, D>(mut self, name: B, value: D) -> Self
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
self.set_style_signal(name, value, false);
self
}
#[inline]
pub fn style_important_signal<B, C>(mut self, name: &str, value: C) -> Self
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
pub fn style_important_signal<B, C, D>(mut self, name: B, value: D) -> Self
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
self.set_style_signal(name, value, true);
self
@ -720,32 +722,34 @@ impl ClassBuilder {
}
#[inline]
pub fn style(mut self, name: &str, value: &str) -> Self {
pub fn style<B: StyleName>(mut self, name: B, value: &str) -> Self {
self.stylesheet = self.stylesheet.style(name, value);
self
}
#[inline]
pub fn style_important(mut self, name: &str, value: &str) -> Self {
pub fn style_important<B: StyleName>(mut self, name: B, value: &str) -> Self {
self.stylesheet = self.stylesheet.style_important(name, value);
self
}
#[inline]
pub fn style_signal<B, C>(mut self, name: &str, value: C) -> Self
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
pub fn style_signal<B, C, D>(mut self, name: B, value: D) -> Self
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
self.stylesheet = self.stylesheet.style_signal(name, value);
self
}
#[inline]
pub fn style_important_signal<B, C>(mut self, name: &str, value: C) -> Self
where B: IntoOptionStr,
C: IntoSignal<Item = B>,
C::Signal: 'static {
pub fn style_important_signal<B, C, D>(mut self, name: B, value: D) -> Self
where B: StyleName + 'static,
C: IntoOptionStr,
D: IntoSignal<Item = C>,
D::Signal: 'static {
self.stylesheet = self.stylesheet.style_important_signal(name, value);
self
@ -799,35 +803,18 @@ mod tests {
.style_signal("foo", always("bar"))
.style_signal("foo", always("bar".to_owned()))
.style_signal("foo", always("bar".to_owned()).map(|x| DerefFn::new(x, |x| x.as_str())))
//.style_signal("foo", always(Arc::new("bar")))
//.style_signal("foo", always(Arc::new("bar".to_owned())))
//.style_signal("foo", always(Rc::new("bar")))
//.style_signal("foo", always(Rc::new("bar".to_owned())))
//.style_signal("foo", always(Box::new("bar")))
//.style_signal("foo", always(Box::new("bar".to_owned())))
//.style_signal("foo", always(Cow::Borrowed(&"bar")))
//.style_signal("foo", always(Cow::Owned::<String>("bar".to_owned())))
.style_signal(["-moz-foo", "-webkit-foo", "foo"], always("bar"))
.style_signal(["-moz-foo", "-webkit-foo", "foo"], always("bar".to_owned()))
.style_signal(["-moz-foo", "-webkit-foo", "foo"], always("bar".to_owned()).map(|x| DerefFn::new(x, |x| x.as_str())))
.style_signal("foo", always(Some("bar")))
.style_signal("foo", always(Some("bar".to_owned())))
.style_signal("foo", always("bar".to_owned()).map(|x| Some(DerefFn::new(x, |x| x.as_str()))))
//.style_signal("foo", always(Some(Arc::new("bar"))))
//.style_signal("foo", always(Some(Arc::new("bar".to_owned()))))
//.style_signal("foo", always(Some(Rc::new("bar"))))
//.style_signal("foo", always(Some(Rc::new("bar".to_owned()))))
//.style_signal("foo", always(Some(Box::new("bar"))))
//.style_signal("foo", always(Some(Box::new("bar".to_owned()))))
//.style_signal("foo", always(Some(Cow::Borrowed(&"bar"))))
//.style_signal("foo", always(Some(Cow::Owned::<String>("bar".to_owned()))))
/*.style_signal("foo", always(Arc::new(Some("bar"))))
.style_signal("foo", always(Arc::new(Some("bar".to_owned()))))
.style_signal("foo", always(Rc::new(Some("bar"))))
.style_signal("foo", always(Rc::new(Some("bar".to_owned()))))
.style_signal("foo", always(Box::new(Some("bar"))))
.style_signal("foo", always(Box::new(Some("bar".to_owned()))))
.style_signal("foo", always(Cow::Borrowed(&Some("bar"))))
.style_signal("foo", always(Cow::Owned::<Option<String>>(Some("bar".to_owned()))))*/
.style_signal(["-moz-foo", "-webkit-foo", "foo"], always(Some("bar")))
.style_signal(["-moz-foo", "-webkit-foo", "foo"], always(Some("bar".to_owned())))
.style_signal(["-moz-foo", "-webkit-foo", "foo"], always("bar".to_owned()).map(|x| Some(DerefFn::new(x, |x| x.as_str()))))
;
}

View File

@ -59,6 +59,11 @@ pub fn set_text(element: &TextNode, value: &str) {
}
#[inline]
fn get_style<A: AsRef<Reference>>(element: &A, name: &str) -> String {
js!( return @{element.as_ref()}.style.getPropertyValue(@{name}); ).try_into().unwrap()
}
#[inline]
fn set_style_raw<A: AsRef<Reference>>(element: &A, name: &str, value: &str, important: bool) {
js! { @(no_return)
@ -67,28 +72,14 @@ fn set_style_raw<A: AsRef<Reference>>(element: &A, name: &str, value: &str, impo
}
// TODO this should be in stdweb
// TODO handle browser prefixes
#[cfg(debug_assertions)]
pub fn set_style<A: AsRef<Reference>>(element: &A, name: &str, value: &str, important: bool) {
// TODO maybe use cfg(debug_assertions) ?
pub fn try_set_style<A: AsRef<Reference>>(element: &A, name: &str, value: &str, important: bool) -> bool {
assert!(value != "");
#[inline]
fn get_style<A: AsRef<Reference>>(element: &A, name: &str) -> String {
js!( return @{element.as_ref()}.style.getPropertyValue(@{name}); ).try_into().unwrap()
}
remove_style(element, name);
set_style_raw(element, name, value, important);
if get_style(element, name) == "" {
panic!("style is incorrect:\n name: {}\n value: {}", name, value);
}
}
#[cfg(not(debug_assertions))]
#[inline]
pub fn set_style<A: AsRef<Reference>>(element: &A, name: &str, value: &str, important: bool) {
set_style_raw(element, name, value, important);
get_style(element, name) != ""
}
// TODO this should be in stdweb

View File

@ -1,5 +1,7 @@
use dom_operations;
use dom::DerefFn;
use std::ops::Deref;
use stdweb::Reference;
pub use animation::AnimatedSignalVec;
@ -16,6 +18,63 @@ impl<A, F> Mixin<A> for F where F: Fn(A) -> A {
}
pub trait StyleName {
fn set_style<A: AsRef<Reference>>(&self, element: &A, value: &str, important: bool);
fn remove_style<A: AsRef<Reference>>(&self, element: &A);
}
impl<'a> StyleName for &'a str {
#[inline]
fn set_style<A: AsRef<Reference>>(&self, element: &A, value: &str, important: bool) {
if !dom_operations::try_set_style(element, self, value, important) {
panic!("style is incorrect:\n name: {}\n value: {}", self, value);
}
}
#[inline]
fn remove_style<A: AsRef<Reference>>(&self, element: &A) {
dom_operations::remove_style(element, self);
}
}
macro_rules! array_style_name {
($size:expr) => {
impl<'a> StyleName for [&'a str; $size] {
#[inline]
fn set_style<A: AsRef<Reference>>(&self, element: &A, value: &str, important: bool) {
let mut okay = false;
for name in self.iter() {
if dom_operations::try_set_style(element, name, value, important) {
okay = true;
}
}
if !okay {
panic!("style is incorrect:\n names: {}\n value: {}", self.join(", "), value);
}
}
#[inline]
fn remove_style<A: AsRef<Reference>>(&self, element: &A) {
for name in self.iter() {
dom_operations::remove_style(element, name);
}
}
}
};
}
macro_rules! array_style_names {
($($size:expr),*) => {
$(array_style_name!($size);)*
};
}
array_style_names!(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32);
// TODO figure out a way to implement this for all of AsRef / Borrow / etc.
// TODO implementations for &String and &mut String
pub trait IntoStr {