add support for htmx attributes

This commit is contained in:
xenia 2023-08-20 04:42:56 -04:00
parent d2c0379311
commit 9fe91ebd2a
3 changed files with 46 additions and 0 deletions

View File

@ -103,6 +103,7 @@ impl Declare {
pub attrs: #attr_type_name, pub attrs: #attr_type_name,
pub data_attributes: Vec<(&'static str, String)>, pub data_attributes: Vec<(&'static str, String)>,
pub aria_attributes: Vec<(&'static str, String)>, pub aria_attributes: Vec<(&'static str, String)>,
pub htmx_attributes: Vec<(&'static str, String)>,
pub events: T::Events, pub events: T::Events,
#body #body
} }
@ -129,6 +130,7 @@ impl Declare {
)); ));
body.extend(quote!(data_attributes: Vec::new(),)); body.extend(quote!(data_attributes: Vec::new(),));
body.extend(quote!(aria_attributes: Vec::new(),)); body.extend(quote!(aria_attributes: Vec::new(),));
body.extend(quote!(htmx_attributes: Vec::new(),));
for (child_name, _, _) in self.req_children() { for (child_name, _, _) in self.req_children() {
body.extend(quote!( #child_name, )); body.extend(quote!( #child_name, ));
@ -178,6 +180,7 @@ impl Declare {
#push_attrs #push_attrs
attributes.extend(self.data_attributes.clone()); attributes.extend(self.data_attributes.clone());
attributes.extend(self.aria_attributes.clone()); attributes.extend(self.aria_attributes.clone());
attributes.extend(self.htmx_attributes.clone());
let mut children = Vec::new(); let mut children = Vec::new();
#req_children #req_children
@ -247,6 +250,10 @@ impl Declare {
for (key, value) in &self.aria_attributes { for (key, value) in &self.aria_attributes {
out.push((key, value.to_string())); out.push((key, value.to_string()));
} }
for (key, value) in &self.htmx_attributes {
out.push((key, value.to_string()));
}
out out
} }
} }
@ -364,6 +371,10 @@ impl Declare {
write!(f, " aria-{}=\"{}\"", key, write!(f, " aria-{}=\"{}\"", key,
crate::escape_html_attribute(value.to_string()))?; crate::escape_html_attribute(value.to_string()))?;
} }
for (key, value) in &self.htmx_attributes {
write!(f, " {}=\"{}\"", key,
crate::escape_html_attribute(value.to_string()))?;
}
write!(f, "{}", self.events)?; write!(f, "{}", self.events)?;
#print_children #print_children
} }

View File

@ -115,6 +115,21 @@ fn extract_aria_attributes(
data data
} }
fn extract_htmx_attrs(attrs: &mut StringyMap<Ident, TokenTree>) -> StringyMap<String, TokenTree> {
let mut data = StringyMap::new();
let keys: Vec<Ident> = attrs.keys().cloned().collect();
for key in keys {
let key_name = key.to_string();
if key_name.starts_with("hx_") || key_name.starts_with("sse_")
|| key_name.starts_with("ws_") {
let value = attrs.remove(&key).unwrap();
let key = str::replace(&key_name, "_", "-");
data.insert(key.to_string(), value);
}
}
data
}
fn process_value(value: &TokenTree) -> TokenStream { fn process_value(value: &TokenTree) -> TokenStream {
match value { match value {
TokenTree::Group(g) if g.delimiter() == Delimiter::Bracket => { TokenTree::Group(g) if g.delimiter() == Delimiter::Bracket => {
@ -165,6 +180,7 @@ impl Element {
let events = extract_event_handlers(&mut self.attributes); let events = extract_event_handlers(&mut self.attributes);
let data_attrs = extract_data_attrs(&mut self.attributes); let data_attrs = extract_data_attrs(&mut self.attributes);
let aria_attrs = extract_aria_attributes(&mut self.attributes); let aria_attrs = extract_aria_attributes(&mut self.attributes);
let htmx_attrs = extract_htmx_attrs(&mut self.attributes);
let attrs = self.attributes.iter().map(|(key, value)| { let attrs = self.attributes.iter().map(|(key, value)| {
( (
key.to_string(), key.to_string(),
@ -246,6 +262,15 @@ impl Element {
)); ));
} }
for (key, value) in htmx_attrs
.iter()
.map(|(k, v)| (TokenTree::from(Literal::string(k)), v.clone()))
{
body.extend(quote!(
element.htmx_attributes.push((#key, #value.into()));
));
}
body.extend(opt_children); body.extend(opt_children);
for (key, value) in events.iter() { for (key, value) in events.iter() {

View File

@ -490,6 +490,16 @@ fn test_aria() {
); );
} }
#[test]
fn test_htmx_attributes() {
use crate as axohtml;
use crate::{dom::DOMTree, html};
let frag: DOMTree<String> = html!(<div hx-ext="sse" sse-connect="/test">"Boo!"</div>);
assert_eq!("<div hx-ext=\"sse\" sse-connect=\"/test\">Boo!</div>", frag.to_string());
}
#[test] #[test]
fn test_js() { fn test_js() {
use crate as axohtml; use crate as axohtml;