more fullstack cleanups: loaders serialize, ServeConfig only (#4785)
* some opinionated cleanups in dioxus-server * add serialize to loader * add `result` to Resource * clippy * fix * writable memos, resources, `onmount`, `.pending`, and `.value()` on actions * fix compile issues * fix typo
This commit is contained in:
1 parent
a3e40a5ea2
commit
7102bc3b6a
33 files changed
+2085
-672
No files matched your search
@@ -0,0 +1,83 @@
|
||||
use anyhow::Context;
|
||||
|
||||
/// An `IndexHtml` represents the contents of an `index.html` file used to serve a web application.
|
||||
///
|
||||
/// This defines the static portion of your web application, typically generated by a tool like `dx`
|
||||
/// in conjunction with wasm-bindgen.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct IndexHtml {
|
||||
pub(crate) head_before_title: String,
|
||||
pub(crate) head_after_title: String,
|
||||
pub(crate) title: String,
|
||||
pub(crate) close_head: String,
|
||||
pub(crate) post_main: String,
|
||||
pub(crate) after_closing_body_tag: String,
|
||||
}
|
||||
|
||||
impl IndexHtml {
|
||||
/// Create a new `IndexHtml` from the raw contents of an `index.html` file.
|
||||
///
|
||||
/// This function will parse the `index.html` and split it into sections for easier manipulation.
|
||||
/// The `root_id` parameter specifies the id of the main application container (e.g., "main")
|
||||
/// which your app will render into.
|
||||
pub(crate) fn new(contents: &str, root_id: &'static str) -> Result<IndexHtml, anyhow::Error> {
|
||||
let (pre_main, post_main) = contents.split_once(&format!("id=\"{root_id}\""))
|
||||
.with_context(|| format!("Failed to find id=\"{root_id}\" in index.html. The id is used to inject the application into the page."))?;
|
||||
|
||||
let post_main = post_main.split_once('>').with_context(|| {
|
||||
format!("Failed to find closing > after id=\"{root_id}\" in index.html.")
|
||||
})?;
|
||||
|
||||
let (pre_main, post_main) = (
|
||||
pre_main.to_string() + &format!("id=\"{root_id}\"") + post_main.0 + ">",
|
||||
post_main.1.to_string(),
|
||||
);
|
||||
|
||||
let (head, close_head) = pre_main.split_once("</head>").with_context(|| {
|
||||
format!("Failed to find closing </head> tag after id=\"{root_id}\" in index.html.")
|
||||
})?;
|
||||
|
||||
let (head, close_head) = (head.to_string(), "</head>".to_string() + close_head);
|
||||
|
||||
let (post_main, after_closing_body_tag) =
|
||||
post_main.split_once("</body>").with_context(|| {
|
||||
format!("Failed to find closing </body> tag after id=\"{root_id}\" in index.html.")
|
||||
})?;
|
||||
|
||||
// Strip out the head if it exists
|
||||
let mut head_before_title = String::new();
|
||||
let mut head_after_title = head;
|
||||
let mut title = String::new();
|
||||
if let Some((new_head_before_title, new_title)) = head_after_title.split_once("<title>") {
|
||||
let (new_title, new_head_after_title) = new_title
|
||||
.split_once("</title>")
|
||||
.context("Failed to find closing </title> tag after <title> in index.html.")?;
|
||||
title = format!("<title>{new_title}</title>");
|
||||
head_before_title = new_head_before_title.to_string();
|
||||
head_after_title = new_head_after_title.to_string();
|
||||
}
|
||||
|
||||
Ok(IndexHtml {
|
||||
head_before_title,
|
||||
head_after_title,
|
||||
title,
|
||||
close_head,
|
||||
post_main: post_main.to_string(),
|
||||
after_closing_body_tag: "</body>".to_string() + after_closing_body_tag,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for IndexHtml {
|
||||
fn default() -> Self {
|
||||
const DEFAULT: &str = r#"<!DOCTYPE html>
|
||||
<html>
|
||||
<head> </head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
</body>
|
||||
</html>"#;
|
||||
|
||||
Self::new(DEFAULT, "main").expect("Failed to load default index.html")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user