fix: add missing attribute-escaping logic in `leptos_meta` and `class` attributes in SSR (closes #1238) (#1241)
This commit is contained in:
parent
ee7dbafc85
commit
13f7cb9a9a
|
@ -581,7 +581,7 @@ fn attribute_to_tokens_ssr<'a>(
|
|||
|| name.strip_prefix("style:").is_some()
|
||||
{
|
||||
// ignore props for SSR
|
||||
// ignore classes and sdtyles: we'll handle these separately
|
||||
// ignore classes and styles: we'll handle these separately
|
||||
} else if name == "inner_html" {
|
||||
return attr.value();
|
||||
} else {
|
||||
|
@ -606,7 +606,9 @@ fn attribute_to_tokens_ssr<'a>(
|
|||
if let Some(value) = value_to_string(value) {
|
||||
template.push_str(&name);
|
||||
template.push_str("=\"");
|
||||
template.push_str(&value);
|
||||
template.push_str(&html_escape::encode_quoted_attribute(
|
||||
&value,
|
||||
));
|
||||
template.push('"');
|
||||
} else {
|
||||
template.push_str("{}");
|
||||
|
@ -729,7 +731,9 @@ fn set_class_attribute_ssr(
|
|||
{
|
||||
template.push_str(" class=\"");
|
||||
|
||||
template.push_str(&static_class_attr);
|
||||
template.push_str(&html_escape::encode_quoted_attribute(
|
||||
&static_class_attr,
|
||||
));
|
||||
|
||||
for (_span, value) in dyn_class_attr {
|
||||
if let Some(value) = value {
|
||||
|
|
|
@ -1,26 +1,37 @@
|
|||
use cfg_if::cfg_if;
|
||||
use leptos::*;
|
||||
#[cfg(feature = "ssr")]
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
/// Contains the current metadata for the document's `<body>`.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct BodyContext {
|
||||
#[cfg(feature = "ssr")]
|
||||
class: Rc<RefCell<Option<TextProp>>>,
|
||||
#[cfg(feature = "ssr")]
|
||||
attributes: Rc<RefCell<Option<MaybeSignal<AdditionalAttributes>>>>,
|
||||
}
|
||||
|
||||
impl BodyContext {
|
||||
/// Converts the `<body>` metadata into an HTML string.
|
||||
#[cfg(any(feature = "ssr", doc))]
|
||||
pub fn as_string(&self) -> Option<String> {
|
||||
let class = self
|
||||
.class
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|val| format!("class=\"{}\"", val.get()));
|
||||
let class = self.class.borrow().as_ref().map(|val| {
|
||||
format!(
|
||||
"class=\"{}\"",
|
||||
leptos::leptos_dom::ssr::escape_attr(&val.get())
|
||||
)
|
||||
});
|
||||
let attributes = self.attributes.borrow().as_ref().map(|val| {
|
||||
val.with(|val| {
|
||||
val.into_iter()
|
||||
.map(|(n, v)| format!("{}=\"{}\"", n, v.get()))
|
||||
.map(|(n, v)| {
|
||||
format!(
|
||||
"{}=\"{}\"",
|
||||
n,
|
||||
leptos::leptos_dom::ssr::escape_attr(&v.get())
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
})
|
||||
|
@ -81,9 +92,6 @@ pub fn Body(
|
|||
#[prop(optional, into)]
|
||||
attributes: Option<MaybeSignal<AdditionalAttributes>>,
|
||||
) -> impl IntoView {
|
||||
#[cfg(debug_assertions)]
|
||||
crate::feature_warning();
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
let el = document().body().expect("there to be a <body> element");
|
||||
|
@ -110,10 +118,17 @@ pub fn Body(
|
|||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if #[cfg(feature = "ssr")] {
|
||||
let meta = crate::use_head(cx);
|
||||
*meta.body.class.borrow_mut() = class;
|
||||
*meta.body.attributes.borrow_mut() = attributes;
|
||||
} else {
|
||||
_ = cx;
|
||||
_ = class;
|
||||
_ = attributes;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
crate::feature_warning();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,53 @@
|
|||
use cfg_if::cfg_if;
|
||||
use leptos::*;
|
||||
#[cfg(feature = "ssr")]
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
/// Contains the current metadata for the document's `<html>`.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct HtmlContext {
|
||||
#[cfg(feature = "ssr")]
|
||||
lang: Rc<RefCell<Option<TextProp>>>,
|
||||
#[cfg(feature = "ssr")]
|
||||
dir: Rc<RefCell<Option<TextProp>>>,
|
||||
#[cfg(feature = "ssr")]
|
||||
class: Rc<RefCell<Option<TextProp>>>,
|
||||
#[cfg(feature = "ssr")]
|
||||
attributes: Rc<RefCell<Option<MaybeSignal<AdditionalAttributes>>>>,
|
||||
}
|
||||
|
||||
impl HtmlContext {
|
||||
/// Converts the `<html>` metadata into an HTML string.
|
||||
#[cfg(any(feature = "ssr", doc))]
|
||||
pub fn as_string(&self) -> Option<String> {
|
||||
let lang = self
|
||||
.lang
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|val| format!("lang=\"{}\"", val.get()));
|
||||
let dir = self
|
||||
.dir
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|val| format!("dir=\"{}\"", val.get()));
|
||||
let class = self
|
||||
.class
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map(|val| format!("class=\"{}\"", val.get()));
|
||||
let lang = self.lang.borrow().as_ref().map(|val| {
|
||||
format!(
|
||||
"lang=\"{}\"",
|
||||
leptos::leptos_dom::ssr::escape_attr(&val.get())
|
||||
)
|
||||
});
|
||||
let dir = self.dir.borrow().as_ref().map(|val| {
|
||||
format!(
|
||||
"dir=\"{}\"",
|
||||
leptos::leptos_dom::ssr::escape_attr(&val.get())
|
||||
)
|
||||
});
|
||||
let class = self.class.borrow().as_ref().map(|val| {
|
||||
format!(
|
||||
"class=\"{}\"",
|
||||
leptos::leptos_dom::ssr::escape_attr(&val.get())
|
||||
)
|
||||
});
|
||||
let attributes = self.attributes.borrow().as_ref().map(|val| {
|
||||
val.with(|val| {
|
||||
val.into_iter()
|
||||
.map(|(n, v)| format!("{}=\"{}\"", n, v.get()))
|
||||
.map(|(n, v)| {
|
||||
format!(
|
||||
"{}=\"{}\"",
|
||||
n,
|
||||
leptos::leptos_dom::ssr::escape_attr(&v.get())
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
})
|
||||
|
@ -96,9 +111,6 @@ pub fn Html(
|
|||
#[prop(optional, into)]
|
||||
attributes: Option<MaybeSignal<AdditionalAttributes>>,
|
||||
) -> impl IntoView {
|
||||
#[cfg(debug_assertions)]
|
||||
crate::feature_warning();
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(feature = "csr", feature = "hydrate"))] {
|
||||
let el = document().document_element().expect("there to be a <html> element");
|
||||
|
@ -139,12 +151,20 @@ pub fn Html(
|
|||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if #[cfg(feature = "ssr")] {
|
||||
let meta = crate::use_head(cx);
|
||||
*meta.html.lang.borrow_mut() = lang;
|
||||
*meta.html.dir.borrow_mut() = dir;
|
||||
*meta.html.class.borrow_mut() = class;
|
||||
*meta.html.attributes.borrow_mut() = attributes;
|
||||
} else {
|
||||
_ = cx;
|
||||
_ = lang;
|
||||
_ = dir;
|
||||
_ = class;
|
||||
_ = attributes;
|
||||
#[cfg(debug_assertions)]
|
||||
crate::feature_warning();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue