refactor(v0): render shell with hemplate
Move the v0 page shell from a Rust format! raw HTML string into a hemplate AppShell view and cover the rendered document structure with scraper. req: html_safety/002 req: view/001 req: test/005
This commit is contained in:
+26
-22
@@ -43,6 +43,11 @@ struct PageSwap {
|
||||
title: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Hemplate)]
|
||||
struct AppShell {
|
||||
body: SafeHtml,
|
||||
}
|
||||
|
||||
#[derive(Hemplate)]
|
||||
#[hemplate = "partials"]
|
||||
struct DocsContent {
|
||||
@@ -180,28 +185,10 @@ fn all_examples() -> String {
|
||||
}
|
||||
|
||||
fn shell(body: String) -> String {
|
||||
format!(
|
||||
r#"<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>slhx v0 examples</title>
|
||||
<script src="/slhx.js" defer></script>
|
||||
<style>
|
||||
body {{ font-family: system-ui, sans-serif; margin: 2rem; max-width: 54rem; }}
|
||||
section, main {{ border: 1px solid #ddd; border-radius: .5rem; margin: 1rem 0; padding: 1rem; }}
|
||||
input, button {{ font: inherit; margin: .25rem; }}
|
||||
nav a {{ margin-right: .75rem; }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>slhx v0 browser examples</h1>
|
||||
<p>Try the counter, todo form, wizard, login, page swap, and live SSE notifications.</p>
|
||||
{body}
|
||||
</body>
|
||||
</html>"#
|
||||
)
|
||||
// req: html_safety/002 req: view/001
|
||||
render_template(&AppShell {
|
||||
body: SafeHtml::trusted(body),
|
||||
})
|
||||
}
|
||||
|
||||
fn render_todos(todos: &[Todo]) -> SafeHtml {
|
||||
@@ -247,6 +234,23 @@ mod tests {
|
||||
Selector::parse(value).expect("test selector parses")
|
||||
}
|
||||
|
||||
// req: html_safety/002 req: view/001 req: test/005
|
||||
#[test]
|
||||
fn shell_is_rendered_by_a_hemplate_view() {
|
||||
let html = shell(render_page_swap("Welcome", "Welcome"));
|
||||
let document = Html::parse_document(&html);
|
||||
assert_eq!(
|
||||
document
|
||||
.select(&selector("title"))
|
||||
.next()
|
||||
.map(|title| title.text().collect::<String>()),
|
||||
Some("slhx v0 examples".to_owned())
|
||||
);
|
||||
assert_eq!(document.select(&selector("script[src=\"/slhx.js\"]")).count(), 1);
|
||||
assert_eq!(document.select(&selector("main[data-slhx-root=\"docs\"]")).count(), 1);
|
||||
assert!(!html.contains("{+="));
|
||||
}
|
||||
|
||||
// req: html_safety/002 req: view/001 req: test/005
|
||||
#[test]
|
||||
fn docs_content_payload_is_rendered_by_a_hemplate_view() {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>slhx v0 examples</title>
|
||||
<script src="/slhx.js" defer></script>
|
||||
<style>
|
||||
body { font-family: system-ui, sans-serif; margin: 2rem; max-width: 54rem; }
|
||||
section, main { border: 1px solid #ddd; border-radius: .5rem; margin: 1rem 0; padding: 1rem; }
|
||||
input, button { font: inherit; margin: .25rem; }
|
||||
nav a { margin-right: .75rem; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>slhx v0 browser examples</h1>
|
||||
<p>Try the counter, todo form, wizard, login, page swap, and live SSE notifications.</p>
|
||||
{+= self.body =+}
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user