feat: inline dioxus-native from blitz (#3675)

* Rename dioxus-blitz to dioxus-native

* Add CSS import support (#139)

* Remove data dependencie from NetProvider + global provider.

* Feat CSS import

* Move net handler code out of util

* Fixing test...

* Use the better suited OnceLock instead of LazyLock

* Removing static and move resource callback back out of the document.

Signed-off-by: koko <kokos.kekse@gmail.com>

* Make things work

Signed-off-by: koko <kokos.kekse@gmail.com>

* Fix the servo example

Signed-off-by: koko <kokos.kekse@gmail.com>

* Replace servo image with a more compact version

Signed-off-by: koko <kokos.kekse@gmail.com>

* revert: 8467b271

Signed-off-by: koko <kokos.kekse@gmail.com>

---------

Signed-off-by: koko <kokos.kekse@gmail.com>

* Create readme app

* WPT: reuse FontContext to avoid reloading system fonts

Takes runtime for css-flexbox from 12s -> 8s

* Move Devtools to traits crate

* Suppress unused variable warning

* Implement net for DioxusDocument

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Eliminate BlitzWindowEvent type

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Make net crate use document id instead of window id

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Rename and document net traits

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Split `dioxus-native` crate into `dioxus-native` and `blitz-shell` crates (#163)

* Rename waker module to event

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Create seperate DioxusNativeApplication

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Rename dioxus-native crate to blitz-shell

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Split blitz-shell out of dioxus-native crate

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Remove need for dioxus-native to depend directly on stylo

---------

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Unnest dioxus-native modules

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Split MutationWriter into it's own module

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Split HtmlDocument into it's own crate

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Rename dom field of Window to doc

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Support prefers-color-scheme (dark mode)

* Remove use of the `todo` macro in event handling and add a comment about it being a todo (#168)

Using the `todo` macro causes a panic when this event is encountered. Noop is preferable in this case as it does not crash the application. This is especially annoying on platforms where `Ime::Enabled` event is sent upon application start even when the user is using a keyboard layout that does not need an IME support. There was added a "TODO" comment that informs about this feature being missing. Most IDEs and code editors have support/plugins/extensions to work with this type of comments and this type of comment is already used widely across the codebase. As such, the information about this feature not being implemented is not lost.

* Upgrade to dioxus 0.6-rc.0

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Fix text input in dioxus-native

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Make dioxus-native depend dioxus-core and dioxus-html rather than dioxus

* Remove "full" feature from tokio

* Move Viewport to blitz_traits

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Make tokio optional in dioxus-native and blitz-shell

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Make SVG support optional

* Abstract renderer behind a trait

blitz-shell no longer depends on blitz-renderer-vello

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Split HTML launch functions out in `blitz` crate

* feat: Add mousedown and mouseup event (#172)

* feat: Add mousedown and mouseup event

* feat: Triggering :active pseudo-class

* fix: Triggering :active pseudo-class

* Rename RendererEvent to DomEvent

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Rename Document to BaseDocument. DocumentLike to Document

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Move event and document abstractions to blitz-traits

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Rename BlitzEvent to BlitzShellEvent

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Restyle when style attribute is mutated

* feat: Support text box mouse selection (#182)

* Rename raw_dom_data to data

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Rename dioxus-native to native

* Add to workspace

* simplify launch module, integrate native

* Fix it up again

* Update cargo lock

* FIx: propagate accessibility feature fla

* implement asset resolver

* add native to feature match in cli

* Implement document and history for native

* use no-op eval

* clippy

* typos

* typo

* Convert logs to trace

* Bump blitz to alpha releases

* unset image data

* fix style integration with blitz

* fix a few lints

* wire up ids

* implement a few more events

* add more helpful todo note

* bump ci to allow edition 2024, use newer nightly

* make clippy happy

* also update matrix tests to rust 2024

* Add autofocus

Co-authored-by: otgerrogla 2356820+otgerrogla@users.noreply.github.com

* Wait for the suspense boundary above the router to resolve before sending the first streaming chunk (#3891)

* Change the suspense streaming context after suspense is resolved in the router

* Wait for the suspense context before streaming the first chunk in ssr

* forward more response parts

* warn

* extract the hydration format into a crate

* Fix hydration when no data is sent

* forward web and server features

* Fix suspense that starts on the client

* fix use_server_future on the client

* Add documentation for fullstack hooks and protocol

* downgrade rust edition

* fix clippy

* fix tests

* fix clippy

* Fix pure web compile

* undo changes to the fullstack router example

* fix formatting

* hoist a bunch of deps

---------

Signed-off-by: koko <kokos.kekse@gmail.com>
Signed-off-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: Nico Burns <nico@nicoburns.com>
Co-authored-by: koko <72217393+kokoISnoTarget@users.noreply.github.com>
Co-authored-by: David Husička <25853767+DavidHusicka@users.noreply.github.com>
Co-authored-by: luoxiaozero <48741584+luoxiaozero@users.noreply.github.com>
Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
Jonathan Kelleyotgerrogla 2356820+otgerrogla@users.noreply.github.comNico BurnskokoDavid HusičkaluoxiaozeroEvan Almloff
authored and GitHub committed 2025-04-08 17:30:49 -07:00
1 parent 84221f55a0
commit 12c6938346
38 files changed
+6156 -2087

No files matched your search

+2
View File
@@ -27,6 +27,7 @@ dioxus-desktop = { workspace = true, default-features = true, optional = true }
dioxus-fullstack = { workspace = true, default-features = true, optional = true }
dioxus-liveview = { workspace = true, optional = true }
dioxus-ssr = { workspace = true, optional = true }
dioxus-native = { workspace = true, optional = true }
manganis = { workspace = true, features = ["dioxus"], optional = true }
dioxus-logger = { workspace = true, optional = true }
warnings = { workspace = true, optional = true }
@@ -66,6 +67,7 @@ web = ["dep:dioxus-web", "dioxus-fullstack?/web", "dioxus-config-macro/web", "de
ssr = ["dep:dioxus-ssr", "dioxus-config-macro/ssr"]
liveview = ["dep:dioxus-liveview", "dioxus-config-macro/liveview"]
server = ["dioxus-fullstack?/axum", "dioxus-fullstack?/server", "ssr", "dioxus-liveview?/axum"]
native = ["dep:dioxus-native"] # todo(jon): decompose the desktop crate such that "webview" is the default and native is opt-in
# This feature just disables the no-renderer-enabled warning
third-party-renderer = []
+165 -141
View File
@@ -6,10 +6,58 @@ use std::any::Any;
use crate::prelude::*;
/// Launch your Dioxus application with the given root component, context and config.
/// The platform will be determined from cargo features.
///
/// For a builder API, see `LaunchBuilder` defined in the `dioxus` crate.
///
/// # Feature selection
///
/// - `web`: Enables the web platform.
/// - `desktop`: Enables the desktop platform.
/// - `mobile`: Enables the mobile (ios + android webview) platform.
/// - `server`: Enables the server (axum + server-side-rendering) platform.
/// - `liveview`: Enables the liveview (websocke) platform.
/// - `native`: Enables the native (wgpu + winit renderer) platform.
///
/// Currently `native` is its own platform that is not compatible with desktop or mobile since it
/// unifies both platforms into one. If "desktop" and "native" are enabled, then the native renderer
/// will be used.
///
/// # Feature priority
///
/// If multiple renderers are enabled, the order of priority goes:
///
/// 1. liveview
/// 2. server
/// 3. native
/// 4. desktop
/// 5. mobile
/// 6. web
///
/// However, we don't recommend enabling multiple renderers at the same time due to feature conflicts
/// and bloating of the binary size.
///
/// # Example
/// ```rust, no_run
/// # use dioxus::prelude::*;
///
/// dioxus::launch(app);
/// fn app() -> Element {
/// rsx! {
/// div { "Hello, world!" }
/// }
/// }
/// ```
pub fn launch(app: fn() -> Element) {
#[allow(deprecated)]
LaunchBuilder::new().launch(app)
}
/// A builder for a fullstack app.
#[must_use]
pub struct LaunchBuilder {
launch_fn: LaunchFn,
platform: KnownPlatform,
contexts: Vec<ContextFn>,
configs: Vec<Box<dyn Any>>,
}
@@ -19,6 +67,16 @@ pub type LaunchFn = fn(fn() -> Element, Vec<ContextFn>, Vec<Box<dyn Any>>);
/// A context function is a Send and Sync closure that returns a boxed trait object
pub type ContextFn = Box<dyn Fn() -> Box<dyn Any> + Send + Sync + 'static>;
enum KnownPlatform {
Web,
Desktop,
Mobile,
Server,
Liveview,
Native,
Other(LaunchFn),
}
#[allow(clippy::redundant_closure)] // clippy doesnt doesn't understand our coercion to fn
impl LaunchBuilder {
/// Create a new builder for your application. This will create a launch configuration for the current platform based on the features enabled on the `dioxus` crate.
@@ -38,9 +96,24 @@ impl LaunchBuilder {
)
)]
pub fn new() -> LaunchBuilder {
let platform = if cfg!(feature = "liveview") {
KnownPlatform::Liveview
} else if cfg!(feature = "server") {
KnownPlatform::Server
} else if cfg!(feature = "native") {
KnownPlatform::Native
} else if cfg!(feature = "desktop") {
KnownPlatform::Desktop
} else if cfg!(feature = "mobile") {
KnownPlatform::Mobile
} else if cfg!(feature = "web") {
KnownPlatform::Web
} else {
panic!("No platform feature enabled. Please enable one of the following features: liveview, desktop, mobile, web, tui, fullstack to use the launch API.")
};
LaunchBuilder {
// We can't use the `current_platform::launch` function directly because it may return ! or ()
launch_fn: |root, contexts, cfg| current_platform::launch(root, contexts, cfg),
platform,
contexts: Vec::new(),
configs: Vec::new(),
}
@@ -51,7 +124,7 @@ impl LaunchBuilder {
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
pub fn web() -> LaunchBuilder {
LaunchBuilder {
launch_fn: web_launch,
platform: KnownPlatform::Web,
contexts: Vec::new(),
configs: Vec::new(),
}
@@ -62,7 +135,7 @@ impl LaunchBuilder {
#[cfg_attr(docsrs, doc(cfg(feature = "desktop")))]
pub fn desktop() -> LaunchBuilder {
LaunchBuilder {
launch_fn: |root, contexts, cfg| dioxus_desktop::launch::launch(root, contexts, cfg),
platform: KnownPlatform::Desktop,
contexts: Vec::new(),
configs: Vec::new(),
}
@@ -73,9 +146,7 @@ impl LaunchBuilder {
#[cfg_attr(docsrs, doc(cfg(all(feature = "fullstack", feature = "server"))))]
pub fn server() -> LaunchBuilder {
LaunchBuilder {
launch_fn: |root, contexts, cfg| {
dioxus_fullstack::server::launch::launch(root, contexts, cfg)
},
platform: KnownPlatform::Server,
contexts: Vec::new(),
configs: Vec::new(),
}
@@ -86,7 +157,7 @@ impl LaunchBuilder {
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
pub fn mobile() -> LaunchBuilder {
LaunchBuilder {
launch_fn: |root, contexts, cfg| dioxus_mobile::launch_cfg(root, contexts, cfg),
platform: KnownPlatform::Mobile,
contexts: Vec::new(),
configs: Vec::new(),
}
@@ -121,14 +192,12 @@ impl LaunchBuilder {
/// ```
pub fn custom(launch_fn: LaunchFn) -> LaunchBuilder {
LaunchBuilder {
launch_fn,
platform: KnownPlatform::Other(launch_fn),
contexts: vec![],
configs: Vec::new(),
}
}
}
impl LaunchBuilder {
/// Inject state into the root component's context that is created on the thread that the app is launched on.
///
/// # Example
@@ -186,9 +255,7 @@ impl LaunchBuilder {
.push(Box::new(move || Box::new(state.clone())));
self
}
}
impl LaunchBuilder {
/// Provide a platform-specific config to the builder.
///
/// # Example
@@ -211,13 +278,28 @@ impl LaunchBuilder {
self
}
fn launch_inner(self, app: fn() -> Element) {
/// Launch your application.
///
#[allow(clippy::diverging_sub_expression)]
pub fn launch(self, app: fn() -> Element) {
let Self {
platform,
contexts,
configs,
} = self;
// Make sure to turn on the logger if the user specified the logger feaature
#[cfg(feature = "logger")]
dioxus_logger::initialize_default();
#[cfg(all(feature = "fullstack", any(feature = "desktop", feature = "mobile")))]
// Set any flags if we're running under fullstack
#[cfg(feature = "fullstack")]
{
use dioxus_fullstack::prelude::server_fn::client::{get_server_url, set_server_url};
// Make sure to set the server_fn endpoint if the user specified the fullstack feature
// We only set this on native targets
#[cfg(any(feature = "desktop", feature = "mobile", feature = "native"))]
if get_server_url().is_empty() {
let serverurl = format!(
"http://{}:{}",
@@ -226,143 +308,85 @@ impl LaunchBuilder {
std::env::var("DIOXUS_DEVSERVER_PORT").unwrap_or_else(|_| "8080".to_string())
)
.leak();
set_server_url(serverurl);
}
// If there is a base path set, call server functions from that base path
#[cfg(feature = "web")]
if let Some(base_path) = dioxus_cli_config::base_path() {
let base_path = base_path.trim_matches('/');
set_server_url(format!("{}/{}", get_server_url(), base_path).leak());
}
}
let cfg = self.configs;
(self.launch_fn)(app, self.contexts, cfg);
}
// If native is specified, we override the webview launcher
#[cfg(feature = "native")]
if matches!(platform, KnownPlatform::Native) {
return dioxus_native::launch_cfg(app, contexts, configs);
}
/// Launch your application.
pub fn launch(self, app: fn() -> Element) {
self.launch_inner(app);
}
}
#[cfg(feature = "mobile")]
if matches!(platform, KnownPlatform::Mobile) {
return dioxus_mobile::launch_bindings::launch(app, contexts, configs);
}
/// Re-export the platform we expect the user wants
///
/// If multiple platforms are enabled, we use this priority (from highest to lowest):
/// - `fullstack`
/// - `desktop`
/// - `mobile`
/// - `web`
/// - `liveview`
mod current_platform {
#[cfg(all(feature = "fullstack", feature = "server"))]
pub use dioxus_fullstack::server::launch::*;
#[cfg(feature = "desktop")]
if matches!(platform, KnownPlatform::Desktop) {
return dioxus_desktop::launch::launch(app, contexts, configs);
}
#[cfg(all(
feature = "desktop",
not(all(feature = "fullstack", feature = "server"))
))]
pub use dioxus_desktop::launch::*;
#[cfg(feature = "server")]
if matches!(platform, KnownPlatform::Server) {
return dioxus_fullstack::server::launch::launch(app, contexts, configs);
}
#[cfg(all(
feature = "mobile",
not(feature = "desktop"),
not(all(feature = "fullstack", feature = "server"))
))]
pub use dioxus_mobile::launch_bindings::*;
#[cfg(feature = "web")]
if matches!(platform, KnownPlatform::Web) {
// If the server feature is enabled, launch the client with hydration enabled
#[cfg(feature = "fullstack")]
{
let platform_config = configs
.into_iter()
.find_map(|cfg| cfg.downcast::<dioxus_web::Config>().ok())
.unwrap_or_default()
.hydrate(true);
#[cfg(all(
feature = "web",
not(all(feature = "fullstack", feature = "server")),
not(all(feature = "server")),
not(feature = "desktop"),
not(feature = "mobile"),
))]
pub fn launch(
root: fn() -> dioxus_core::Element,
contexts: Vec<super::ContextFn>,
platform_config: Vec<Box<dyn std::any::Any>>,
) {
super::web_launch(root, contexts, platform_config);
}
let mut vdom = dioxus_core::VirtualDom::new(app);
for context in contexts {
vdom.insert_any_root_context(context());
}
#[cfg(all(
feature = "liveview",
not(all(feature = "fullstack", feature = "server")),
not(all(feature = "server")),
not(feature = "desktop"),
not(feature = "mobile"),
not(feature = "web"),
))]
pub use dioxus_liveview::launch::*;
#[cfg(feature = "document")]
{
use dioxus_fullstack::document;
let document = std::rc::Rc::new(document::web::FullstackWebDocument)
as std::rc::Rc<dyn crate::prelude::document::Document>;
vdom.provide_root_context(document);
}
#[cfg(not(any(
feature = "liveview",
all(feature = "fullstack", feature = "server"),
all(feature = "server"),
feature = "desktop",
feature = "mobile",
feature = "web",
)))]
pub fn launch(
root: fn() -> dioxus_core::Element,
contexts: Vec<super::ContextFn>,
platform_config: Vec<Box<dyn std::any::Any>>,
) {
#[cfg(feature = "third-party-renderer")]
panic!("No first party renderer feature enabled. It looks like you are trying to use a third party renderer. You will need to use the launch function from the third party renderer crate.");
return dioxus_web::launch::launch_virtual_dom(vdom, platform_config);
}
#[cfg(not(any(feature = "fullstack")))]
return dioxus_web::launch::launch(app, contexts, configs);
}
#[cfg(feature = "liveview")]
if matches!(platform, KnownPlatform::Liveview) {
return dioxus_liveview::launch::launch(app, contexts, configs);
}
// If the platform is not one of the above, then we assume it's a custom platform
if let KnownPlatform::Other(launch_fn) = platform {
return launch_fn(app, contexts, configs);
}
// If we're here, then we have no platform feature enabled and third-party-renderer is enabled
if cfg!(feature = "third-party-renderer") {
panic!("No first party renderer feature enabled. It looks like you are trying to use a third party renderer. You will need to use the launch function from the third party renderer crate.");
}
panic!("No platform feature enabled. Please enable one of the following features: liveview, desktop, mobile, web, tui, fullstack to use the launch API.")
}
}
pub fn launch(app: fn() -> Element) {
#[allow(deprecated)]
LaunchBuilder::new().launch(app)
}
#[cfg(feature = "web")]
fn web_launch(
root: fn() -> dioxus_core::Element,
contexts: Vec<super::ContextFn>,
platform_config: Vec<Box<dyn std::any::Any>>,
) {
// If the server feature is enabled, launch the client with hydration enabled
#[cfg(feature = "fullstack")]
{
let platform_config = platform_config
.into_iter()
.find_map(|cfg| cfg.downcast::<dioxus_web::Config>().ok())
.unwrap_or_default()
.hydrate(true);
// If there is a base path set, call server functions from that base path
if let Some(base_path) = dioxus_cli_config::web_base_path() {
let base_path = base_path.trim_matches('/');
crate::prelude::server_fn::client::set_server_url(
format!(
"{}/{}",
crate::prelude::server_fn::client::get_server_url(),
base_path
)
.leak(),
);
}
let factory = move || {
let mut vdom = dioxus_core::VirtualDom::new(root);
for context in contexts {
vdom.insert_any_root_context(context());
}
#[cfg(feature = "document")]
{
#[cfg(feature = "fullstack")]
use dioxus_fullstack::document;
let document = std::rc::Rc::new(document::web::FullstackWebDocument)
as std::rc::Rc<dyn crate::prelude::document::Document>;
vdom.provide_root_context(document);
}
vdom
};
dioxus_web::launch::launch_virtual_dom(factory(), platform_config)
}
#[cfg(not(any(feature = "fullstack")))]
dioxus_web::launch::launch(root, contexts, platform_config);
}