mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
This commit is contained in:
parent
2c7ee0d415
commit
f969fd7eff
3 changed files with 71 additions and 23 deletions
|
@ -244,19 +244,28 @@ fn fragments_to_chunks(
|
|||
impl View {
|
||||
/// Consumes the node and renders it into an HTML string.
|
||||
pub fn render_to_string(self, _cx: Scope) -> Cow<'static, str> {
|
||||
self.render_to_string_helper()
|
||||
self.render_to_string_helper(false)
|
||||
}
|
||||
|
||||
pub(crate) fn render_to_string_helper(self) -> Cow<'static, str> {
|
||||
pub(crate) fn render_to_string_helper(
|
||||
self,
|
||||
dont_escape_text: bool,
|
||||
) -> Cow<'static, str> {
|
||||
match self {
|
||||
View::Text(node) => {
|
||||
html_escape::encode_safe(&node.content).to_string().into()
|
||||
if dont_escape_text {
|
||||
node.content
|
||||
} else {
|
||||
html_escape::encode_safe(&node.content).to_string().into()
|
||||
}
|
||||
}
|
||||
View::Component(node) => {
|
||||
let content = || {
|
||||
node.children
|
||||
.into_iter()
|
||||
.map(|node| node.render_to_string_helper())
|
||||
.map(|node| {
|
||||
node.render_to_string_helper(dont_escape_text)
|
||||
})
|
||||
.join("")
|
||||
};
|
||||
cfg_if! {
|
||||
|
@ -283,7 +292,8 @@ impl View {
|
|||
}
|
||||
View::Suspense(id, node) => format!(
|
||||
"<!--suspense-open-{id}-->{}<!--suspense-close-{id}-->",
|
||||
View::CoreComponent(node).render_to_string_helper()
|
||||
View::CoreComponent(node)
|
||||
.render_to_string_helper(dont_escape_text)
|
||||
)
|
||||
.into(),
|
||||
View::CoreComponent(node) => {
|
||||
|
@ -333,7 +343,9 @@ impl View {
|
|||
t.content
|
||||
}
|
||||
} else {
|
||||
child.render_to_string_helper()
|
||||
child.render_to_string_helper(
|
||||
dont_escape_text,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
"".into()
|
||||
|
@ -356,7 +368,9 @@ impl View {
|
|||
let id = node.id;
|
||||
|
||||
let content = || {
|
||||
node.child.render_to_string_helper()
|
||||
node.child.render_to_string_helper(
|
||||
dont_escape_text,
|
||||
)
|
||||
};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -409,6 +423,8 @@ impl View {
|
|||
}
|
||||
}
|
||||
View::Element(el) => {
|
||||
let is_script_or_style =
|
||||
el.name == "script" || el.name == "style";
|
||||
let el_html = if let ElementChildren::Chunks(chunks) =
|
||||
el.children
|
||||
{
|
||||
|
@ -416,9 +432,8 @@ impl View {
|
|||
.into_iter()
|
||||
.map(|chunk| match chunk {
|
||||
StringOrView::String(string) => string,
|
||||
StringOrView::View(view) => {
|
||||
view().render_to_string_helper()
|
||||
}
|
||||
StringOrView::View(view) => view()
|
||||
.render_to_string_helper(is_script_or_style),
|
||||
})
|
||||
.join("")
|
||||
.into()
|
||||
|
@ -460,7 +475,11 @@ impl View {
|
|||
ElementChildren::Empty => "".into(),
|
||||
ElementChildren::Children(c) => c
|
||||
.into_iter()
|
||||
.map(View::render_to_string_helper)
|
||||
.map(|v| {
|
||||
v.render_to_string_helper(
|
||||
is_script_or_style,
|
||||
)
|
||||
})
|
||||
.join("")
|
||||
.into(),
|
||||
ElementChildren::InnerHtml(h) => h,
|
||||
|
|
|
@ -213,7 +213,7 @@ impl View {
|
|||
/// Renders the view into a set of HTML chunks that can be streamed.
|
||||
pub fn into_stream_chunks(self, cx: Scope) -> VecDeque<StreamChunk> {
|
||||
let mut chunks = VecDeque::new();
|
||||
self.into_stream_chunks_helper(cx, &mut chunks);
|
||||
self.into_stream_chunks_helper(cx, &mut chunks, false);
|
||||
chunks
|
||||
}
|
||||
|
||||
|
@ -221,6 +221,7 @@ impl View {
|
|||
self,
|
||||
cx: Scope,
|
||||
chunks: &mut VecDeque<StreamChunk>,
|
||||
dont_escape_text: bool,
|
||||
) {
|
||||
match self {
|
||||
View::Suspense(id, _) => {
|
||||
|
@ -241,18 +242,21 @@ impl View {
|
|||
let name = crate::ssr::to_kebab_case(&node.name);
|
||||
chunks.push_back(StreamChunk::Sync(format!(r#"<!--hk={}|leptos-{name}-start-->"#, HydrationCtx::to_string(&node.id, false)).into()));
|
||||
for child in node.children {
|
||||
child.into_stream_chunks_helper(cx, chunks);
|
||||
child.into_stream_chunks_helper(cx, chunks, dont_escape_text);
|
||||
}
|
||||
chunks.push_back(StreamChunk::Sync(format!(r#"<!--hk={}|leptos-{name}-end-->"#, HydrationCtx::to_string(&node.id, true)).into()));
|
||||
} else {
|
||||
for child in node.children {
|
||||
child.into_stream_chunks_helper(cx, chunks);
|
||||
child.into_stream_chunks_helper(cx, chunks, dont_escape_text);
|
||||
}
|
||||
chunks.push_back(StreamChunk::Sync(format!(r#"<!--hk={}-->"#, HydrationCtx::to_string(&node.id, true)).into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
View::Element(el) => {
|
||||
let is_script_or_style =
|
||||
el.name == "script" || el.name == "style";
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
if let Some(id) = &el.view_marker {
|
||||
chunks.push_back(StreamChunk::Sync(
|
||||
|
@ -266,7 +270,11 @@ impl View {
|
|||
chunks.push_back(StreamChunk::Sync(string))
|
||||
}
|
||||
StringOrView::View(view) => {
|
||||
view().into_stream_chunks_helper(cx, chunks);
|
||||
view().into_stream_chunks_helper(
|
||||
cx,
|
||||
chunks,
|
||||
is_script_or_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -318,7 +326,11 @@ impl View {
|
|||
ElementChildren::Empty => {}
|
||||
ElementChildren::Children(children) => {
|
||||
for child in children {
|
||||
child.into_stream_chunks_helper(cx, chunks);
|
||||
child.into_stream_chunks_helper(
|
||||
cx,
|
||||
chunks,
|
||||
is_script_or_style,
|
||||
);
|
||||
}
|
||||
}
|
||||
ElementChildren::InnerHtml(inner_html) => {
|
||||
|
@ -387,22 +399,33 @@ impl View {
|
|||
// into one single node, so we need to artificially make the
|
||||
// browser create the dynamic text as it's own text node
|
||||
if let View::Text(t) = child {
|
||||
let content = if dont_escape_text {
|
||||
t.content.into()
|
||||
} else {
|
||||
html_escape::encode_safe(
|
||||
&t.content,
|
||||
)
|
||||
.to_string()
|
||||
.into()
|
||||
};
|
||||
chunks.push_back(
|
||||
if !cfg!(debug_assertions) {
|
||||
StreamChunk::Sync(
|
||||
format!(
|
||||
"<!>{}",
|
||||
html_escape::encode_safe(&t.content)
|
||||
content
|
||||
)
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
StreamChunk::Sync(html_escape::encode_safe(&t.content).to_string().into())
|
||||
StreamChunk::Sync(content)
|
||||
},
|
||||
);
|
||||
} else {
|
||||
child.into_stream_chunks_helper(
|
||||
cx, chunks,
|
||||
cx,
|
||||
chunks,
|
||||
dont_escape_text,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +458,9 @@ impl View {
|
|||
);
|
||||
node.child
|
||||
.into_stream_chunks_helper(
|
||||
cx, chunks,
|
||||
cx,
|
||||
chunks,
|
||||
dont_escape_text,
|
||||
);
|
||||
chunks.push_back(
|
||||
StreamChunk::Sync(
|
||||
|
|
|
@ -393,6 +393,7 @@ fn element_to_tokens_ssr(
|
|||
.to_string()
|
||||
.replace("svg::", "")
|
||||
.replace("math::", "");
|
||||
let is_script_or_style = tag_name == "script" || tag_name == "style";
|
||||
template.push('<');
|
||||
template.push_str(&tag_name);
|
||||
|
||||
|
@ -461,9 +462,12 @@ fn element_to_tokens_ssr(
|
|||
}
|
||||
Node::Text(text) => {
|
||||
if let Some(value) = value_to_string(&text.value) {
|
||||
template.push_str(&html_escape::encode_safe(
|
||||
&value,
|
||||
));
|
||||
let value = if is_script_or_style {
|
||||
value.into()
|
||||
} else {
|
||||
html_escape::encode_safe(&value)
|
||||
};
|
||||
template.push_str(&value);
|
||||
} else {
|
||||
template.push_str("{}");
|
||||
let value = text.value.as_ref();
|
||||
|
|
Loading…
Reference in a new issue