diff --git a/benches/tui_update.rs b/benches/tui_update.rs
index 5a3a70b66..d46921a8d 100644
--- a/benches/tui_update.rs
+++ b/benches/tui_update.rs
@@ -17,62 +17,14 @@ fn tui_update(c: &mut Criterion) {
&size,
|b, size| {
b.iter(|| match size {
- 1 => dioxus::tui::launch_cfg(
- app3,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 2 => dioxus::tui::launch_cfg(
- app6,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 3 => dioxus::tui::launch_cfg(
- app9,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 4 => dioxus::tui::launch_cfg(
- app12,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 5 => dioxus::tui::launch_cfg(
- app15,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 6 => dioxus::tui::launch_cfg(
- app18,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 7 => dioxus::tui::launch_cfg(
- app21,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
- 8 => dioxus::tui::launch_cfg(
- app24,
- Config {
- headless: true,
- ..Default::default()
- },
- ),
+ 1 => dioxus::tui::launch_cfg(app3, Config::default().with_headless()),
+ 2 => dioxus::tui::launch_cfg(app6, Config::default().with_headless()),
+ 3 => dioxus::tui::launch_cfg(app9, Config::default().with_headless()),
+ 4 => dioxus::tui::launch_cfg(app12, Config::default().with_headless()),
+ 5 => dioxus::tui::launch_cfg(app15, Config::default().with_headless()),
+ 6 => dioxus::tui::launch_cfg(app18, Config::default().with_headless()),
+ 7 => dioxus::tui::launch_cfg(app21, Config::default().with_headless()),
+ 8 => dioxus::tui::launch_cfg(app24, Config::default().with_headless()),
_ => (),
})
},
diff --git a/examples/custom_html.rs b/examples/custom_html.rs
new file mode 100644
index 000000000..02f603710
--- /dev/null
+++ b/examples/custom_html.rs
@@ -0,0 +1,37 @@
+//! This example shows how to use a custom index.html and custom
extensions
+//! to add things like stylesheets, scripts, and third-party JS libraries.
+
+use dioxus::prelude::*;
+
+fn main() {
+ dioxus::desktop::launch_cfg(app, |c| {
+ c.with_custom_head("".into())
+ });
+
+ dioxus::desktop::launch_cfg(app, |c| {
+ c.with_custom_index(
+ r#"
+
+
+
+ Dioxus app
+
+
+
+
+
+
+
+ "#
+ .into(),
+ )
+ });
+}
+
+fn app(cx: Scope) -> Element {
+ cx.render(rsx! {
+ div {
+ h1 {"hello world!"}
+ }
+ })
+}
diff --git a/examples/tailwind.rs b/examples/tailwind.rs
index 6611fc47b..e0cb2339a 100644
--- a/examples/tailwind.rs
+++ b/examples/tailwind.rs
@@ -11,12 +11,13 @@
use dioxus::prelude::*;
fn main() {
- dioxus::desktop::launch(app);
+ dioxus::desktop::launch_cfg(app, |c| {
+ c.with_custom_head("".to_string())
+ });
}
pub fn app(cx: Scope) -> Element {
cx.render(rsx!(
- link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", rel:"stylesheet" }
div {
header { class: "text-gray-400 bg-gray-900 body-font",
div { class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center",
diff --git a/examples/tui_color_test.rs b/examples/tui_color_test.rs
index d9ebad275..1a5a67457 100644
--- a/examples/tui_color_test.rs
+++ b/examples/tui_color_test.rs
@@ -3,10 +3,7 @@ use dioxus::prelude::*;
fn main() {
dioxus::tui::launch_cfg(
app,
- dioxus::tui::Config {
- rendering_mode: dioxus::tui::RenderingMode::Ansi,
- ..Default::default()
- },
+ dioxus::tui::Config::default().with_rendering_mode(dioxus::tui::RenderingMode::Ansi),
);
}
diff --git a/packages/desktop/src/cfg.rs b/packages/desktop/src/cfg.rs
index 6028706bc..84ac3a72a 100644
--- a/packages/desktop/src/cfg.rs
+++ b/packages/desktop/src/cfg.rs
@@ -21,6 +21,8 @@ pub struct DesktopConfig {
pub(crate) event_handler: Option>,
pub(crate) disable_context_menu: bool,
pub(crate) resource_dir: Option,
+ pub(crate) custom_head: Option,
+ pub(crate) custom_index: Option,
}
pub(crate) type WryProtocol = (
@@ -42,6 +44,8 @@ impl DesktopConfig {
pre_rendered: None,
disable_context_menu: !cfg!(debug_assertions),
resource_dir: None,
+ custom_head: None,
+ custom_index: None,
}
}
@@ -100,10 +104,30 @@ impl DesktopConfig {
self
}
+ /// Add a custom icon for this application
pub fn with_icon(&mut self, icon: Icon) -> &mut Self {
self.window.window.window_icon = Some(icon);
self
}
+
+ /// Inject additional content into the document's HEAD.
+ ///
+ /// This is useful for loading CSS libraries, JS libraries, etc.
+ pub fn with_custom_head(&mut self, head: String) -> &mut Self {
+ self.custom_head = Some(head);
+ self
+ }
+
+ /// Use a custom index.html instead of the default Dioxus one.
+ ///
+ /// Make sure your index.html is valid HTML.
+ ///
+ /// Dioxus injects some loader code into the closing body tag. Your document
+ /// must include a body element!
+ pub fn with_custom_index(&mut self, index: String) -> &mut Self {
+ self.custom_index = Some(index);
+ self
+ }
}
impl DesktopConfig {
diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs
index 4ad2ff3a7..155f7af1b 100644
--- a/packages/desktop/src/desktop_context.rs
+++ b/packages/desktop/src/desktop_context.rs
@@ -201,7 +201,7 @@ pub(super) fn handler(
/// Get a closure that executes any JavaScript in the WebView context.
pub fn use_eval(cx: &ScopeState) -> &dyn Fn(S) {
- let desktop = use_window(&cx).clone();
+ let desktop = use_window(cx).clone();
cx.use_hook(|_| move |script| desktop.eval(script))
}
diff --git a/packages/desktop/src/index.html b/packages/desktop/src/index.html
index 292a1ae6a..0704fd0f0 100644
--- a/packages/desktop/src/index.html
+++ b/packages/desktop/src/index.html
@@ -3,13 +3,10 @@
Dioxus app
+
-
+
diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs
index 596956c53..1e3898f05 100644
--- a/packages/desktop/src/lib.rs
+++ b/packages/desktop/src/lib.rs
@@ -125,8 +125,9 @@ pub fn launch_with_props(
let proxy = proxy.clone();
let file_handler = cfg.file_drop_handler.take();
-
+ let custom_head = cfg.custom_head.clone();
let resource_dir = cfg.resource_dir.clone();
+ let index_file = cfg.custom_index.clone();
let mut webview = WebViewBuilder::new(window)
.unwrap()
@@ -164,7 +165,12 @@ pub fn launch_with_props(
});
})
.with_custom_protocol(String::from("dioxus"), move |r| {
- protocol::desktop_handler(r, resource_dir.clone())
+ protocol::desktop_handler(
+ r,
+ resource_dir.clone(),
+ custom_head.clone(),
+ index_file.clone(),
+ )
})
.with_file_drop_handler(move |window, evet| {
file_handler
@@ -183,12 +189,10 @@ pub fn launch_with_props(
r#"
if (document.addEventListener) {
document.addEventListener('contextmenu', function(e) {
- alert("You've tried to open context menu");
e.preventDefault();
}, false);
} else {
document.attachEvent('oncontextmenu', function() {
- alert("You've tried to open context menu");
window.event.returnValue = false;
});
}
diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs
index bd8bb3d84..085c3c32d 100644
--- a/packages/desktop/src/protocol.rs
+++ b/packages/desktop/src/protocol.rs
@@ -4,7 +4,20 @@ use wry::{
Result,
};
-pub(super) fn desktop_handler(request: &Request, asset_root: Option) -> Result {
+const MODULE_LOADER: &str = r#"
+
+"#;
+
+pub(super) fn desktop_handler(
+ request: &Request,
+ asset_root: Option,
+ custom_head: Option,
+ custom_index: Option,
+) -> Result {
// Any content that uses the `dioxus://` scheme will be shuttled through this handler as a "special case".
// For now, we only serve two pieces of content which get included as bytes into the final binary.
let path = request.uri().replace("dioxus://", "");
@@ -13,9 +26,25 @@ pub(super) fn desktop_handler(request: &Request, asset_root: Option) ->
let trimmed = path.trim_start_matches("index.html/");
if trimmed.is_empty() {
- ResponseBuilder::new()
- .mimetype("text/html")
- .body(include_bytes!("./index.html").to_vec())
+ // If a custom index is provided, just defer to that, expecting the user to know what they're doing.
+ // we'll look for the closing