mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-02-17 06:08:26 +00:00
Merge branch 'DioxusLabs:master' into fix-links-liveview
This commit is contained in:
commit
c0d08c9802
21 changed files with 507 additions and 17 deletions
|
@ -23,6 +23,7 @@ members = [
|
|||
"packages/signals",
|
||||
"packages/hot-reload",
|
||||
"docs/guide",
|
||||
"examples/PWA-example",
|
||||
]
|
||||
|
||||
# This is a "virtual package"
|
||||
|
|
17
examples/PWA-example/Cargo.toml
Normal file
17
examples/PWA-example/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "dioxus-pwa-example"
|
||||
version = "0.1.0"
|
||||
authors = ["Antonio Curavalea <one.kyonblack@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
dioxus = { path = "../../packages/dioxus", version = "^0.3.0"}
|
||||
dioxus-web = { path = "../../packages/web", version = "^0.3.0"}
|
||||
|
||||
log = "0.4.6"
|
||||
|
||||
# WebAssembly Debug
|
||||
wasm-logger = "0.2.0"
|
||||
console_error_panic_hook = "0.1.7"
|
42
examples/PWA-example/Dioxus.toml
Normal file
42
examples/PWA-example/Dioxus.toml
Normal file
|
@ -0,0 +1,42 @@
|
|||
[application]
|
||||
|
||||
# App (Project) Name
|
||||
name = "dioxus-pwa-example"
|
||||
|
||||
# Dioxus App Default Platform
|
||||
# desktop, web, mobile, ssr
|
||||
default_platform = "web"
|
||||
|
||||
# `build` & `serve` dist path
|
||||
out_dir = "dist"
|
||||
|
||||
# resource (public) file folder
|
||||
asset_dir = "public"
|
||||
|
||||
[web.app]
|
||||
|
||||
# HTML title tag content
|
||||
title = "dioxus | ⛺"
|
||||
|
||||
[web.watcher]
|
||||
|
||||
# when watcher trigger, regenerate the `index.html`
|
||||
reload_html = true
|
||||
|
||||
# which files or dirs will be watcher monitoring
|
||||
watch_path = ["src", "public"]
|
||||
|
||||
# include `assets` in web platform
|
||||
[web.resource]
|
||||
|
||||
# CSS style file
|
||||
style = []
|
||||
|
||||
# Javascript code file
|
||||
script = []
|
||||
|
||||
[web.resource.dev]
|
||||
|
||||
# Javascript code file
|
||||
# serve: [dev-server] only
|
||||
script = []
|
21
examples/PWA-example/LICENSE
Normal file
21
examples/PWA-example/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Dioxus
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
44
examples/PWA-example/README.md
Normal file
44
examples/PWA-example/README.md
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Dioxus PWA example
|
||||
|
||||
This is a basic example of a progressive web app (PWA) using Dioxus and Dioxus CLI.
|
||||
Currently PWA functionality requires the use of a service worker and manifest file, so this isn't 100% Rust yet.
|
||||
|
||||
It is also very much usable as a template for your projects, if you're aiming to create a PWA.
|
||||
|
||||
## Try the example
|
||||
|
||||
Make sure you have Dioxus CLI installed (if you're unsure, run `cargo install dioxus-cli`).
|
||||
|
||||
You can run `dioxus serve` in this directory to start the web server locally, or run
|
||||
`dioxus build --release` to build the project so you can deploy it on a separate web-server.
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
├── Cargo.toml
|
||||
├── Dioxus.toml
|
||||
├── index.html // Custom HTML is needed for this, to load the SW and manifest.
|
||||
├── LICENSE
|
||||
├── public
|
||||
│ ├── favicon.ico
|
||||
│ ├── logo_192.png
|
||||
│ ├── logo_512.png
|
||||
│ ├── manifest.json // The manifest file - edit this as you need to.
|
||||
│ └── sw.js // The service worker - you must edit this for actual projects.
|
||||
├── README.md
|
||||
└── src
|
||||
└── main.rs
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
If you're just getting started with PWAs, here are some useful resources:
|
||||
|
||||
* [PWABuilder docs](https://docs.pwabuilder.com/#/)
|
||||
* [MDN article on PWAs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)
|
||||
|
||||
For service worker scripting (in JavaScript):
|
||||
|
||||
* [Service worker guide from PWABuilder](https://docs.pwabuilder.com/#/home/sw-intro)
|
||||
* [Service worker examples, also from PWABuilder](https://github.com/pwa-builder/pwabuilder-serviceworkers)
|
||||
|
||||
If you want to stay as close to 100% Rust as possible, you can try using [wasi-worker](https://github.com/dunnock/wasi-worker) to replace the JS service worker file. The JSON manifest will still be required though.
|
30
examples/PWA-example/index.html
Normal file
30
examples/PWA-example/index.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{app_title}</title>
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register(
|
||||
'/sw.js'
|
||||
);
|
||||
}
|
||||
</script>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta charset="UTF-8" />
|
||||
{style_include}
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
<script type="module">
|
||||
import init from "/{base_path}/assets/dioxus/{app_name}.js";
|
||||
init("/{base_path}/assets/dioxus/{app_name}_bg.wasm").then(wasm => {
|
||||
if (wasm.__wbindgen_start == undefined) {
|
||||
wasm.main();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{script_include}
|
||||
</body>
|
||||
</html>
|
BIN
examples/PWA-example/public/favicon.ico
Normal file
BIN
examples/PWA-example/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
examples/PWA-example/public/logo_192.png
Normal file
BIN
examples/PWA-example/public/logo_192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
examples/PWA-example/public/logo_512.png
Normal file
BIN
examples/PWA-example/public/logo_512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
34
examples/PWA-example/public/manifest.json
Normal file
34
examples/PWA-example/public/manifest.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "Dioxus",
|
||||
"icons": [
|
||||
{
|
||||
"src": "logo_192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo_512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512",
|
||||
"purpose": "any"
|
||||
},
|
||||
{
|
||||
"src": "logo_512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "any",
|
||||
"purpose": "any"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"id": "/",
|
||||
"display": "standalone",
|
||||
"display_override": ["window-control-overlay", "standalone"],
|
||||
"scope": "/",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff",
|
||||
"short_name": "Dioxus",
|
||||
"description": "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust.",
|
||||
"dir": "ltr",
|
||||
"lang": "en",
|
||||
"orientation": "portrait"
|
||||
}
|
198
examples/PWA-example/public/sw.js
Normal file
198
examples/PWA-example/public/sw.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
"use strict";
|
||||
|
||||
//console.log('WORKER: executing.');
|
||||
|
||||
/* A version number is useful when updating the worker logic,
|
||||
allowing you to remove outdated cache entries during the update.
|
||||
*/
|
||||
var version = 'v1.0.0::';
|
||||
|
||||
/* These resources will be downloaded and cached by the service worker
|
||||
during the installation process. If any resource fails to be downloaded,
|
||||
then the service worker won't be installed either.
|
||||
*/
|
||||
var offlineFundamentals = [
|
||||
// add here the files you want to cache
|
||||
'favicon.ico'
|
||||
];
|
||||
|
||||
/* The install event fires when the service worker is first installed.
|
||||
You can use this event to prepare the service worker to be able to serve
|
||||
files while visitors are offline.
|
||||
*/
|
||||
self.addEventListener("install", function (event) {
|
||||
//console.log('WORKER: install event in progress.');
|
||||
/* Using event.waitUntil(p) blocks the installation process on the provided
|
||||
promise. If the promise is rejected, the service worker won't be installed.
|
||||
*/
|
||||
event.waitUntil(
|
||||
/* The caches built-in is a promise-based API that helps you cache responses,
|
||||
as well as finding and deleting them.
|
||||
*/
|
||||
caches
|
||||
/* You can open a cache by name, and this method returns a promise. We use
|
||||
a versioned cache name here so that we can remove old cache entries in
|
||||
one fell swoop later, when phasing out an older service worker.
|
||||
*/
|
||||
.open(version + 'fundamentals')
|
||||
.then(function (cache) {
|
||||
/* After the cache is opened, we can fill it with the offline fundamentals.
|
||||
The method below will add all resources in `offlineFundamentals` to the
|
||||
cache, after making requests for them.
|
||||
*/
|
||||
return cache.addAll(offlineFundamentals);
|
||||
})
|
||||
.then(function () {
|
||||
//console.log('WORKER: install completed');
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
/* The fetch event fires whenever a page controlled by this service worker requests
|
||||
a resource. This isn't limited to `fetch` or even XMLHttpRequest. Instead, it
|
||||
comprehends even the request for the HTML page on first load, as well as JS and
|
||||
CSS resources, fonts, any images, etc.
|
||||
*/
|
||||
self.addEventListener("fetch", function (event) {
|
||||
//console.log('WORKER: fetch event in progress.');
|
||||
|
||||
/* We should only cache GET requests, and deal with the rest of method in the
|
||||
client-side, by handling failed POST,PUT,PATCH,etc. requests.
|
||||
*/
|
||||
if (event.request.method !== 'GET') {
|
||||
/* If we don't block the event as shown below, then the request will go to
|
||||
the network as usual.
|
||||
*/
|
||||
//console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
|
||||
return;
|
||||
}
|
||||
/* Similar to event.waitUntil in that it blocks the fetch event on a promise.
|
||||
Fulfillment result will be used as the response, and rejection will end in a
|
||||
HTTP response indicating failure.
|
||||
*/
|
||||
event.respondWith(
|
||||
caches
|
||||
/* This method returns a promise that resolves to a cache entry matching
|
||||
the request. Once the promise is settled, we can then provide a response
|
||||
to the fetch request.
|
||||
*/
|
||||
.match(event.request)
|
||||
.then(function (cached) {
|
||||
/* Even if the response is in our cache, we go to the network as well.
|
||||
This pattern is known for producing "eventually fresh" responses,
|
||||
where we return cached responses immediately, and meanwhile pull
|
||||
a network response and store that in the cache.
|
||||
|
||||
Read more:
|
||||
https://ponyfoo.com/articles/progressive-networking-serviceworker
|
||||
*/
|
||||
var networked = fetch(event.request)
|
||||
// We handle the network request with success and failure scenarios.
|
||||
.then(fetchedFromNetwork, unableToResolve)
|
||||
// We should catch errors on the fetchedFromNetwork handler as well.
|
||||
.catch(unableToResolve);
|
||||
|
||||
/* We return the cached response immediately if there is one, and fall
|
||||
back to waiting on the network as usual.
|
||||
*/
|
||||
//console.log('WORKER: fetch event', cached ? '(cached)' : '(network)', event.request.url);
|
||||
return cached || networked;
|
||||
|
||||
function fetchedFromNetwork(response) {
|
||||
/* We copy the response before replying to the network request.
|
||||
This is the response that will be stored on the ServiceWorker cache.
|
||||
*/
|
||||
var cacheCopy = response.clone();
|
||||
|
||||
//console.log('WORKER: fetch response from network.', event.request.url);
|
||||
|
||||
caches
|
||||
// We open a cache to store the response for this request.
|
||||
.open(version + 'pages')
|
||||
.then(function add(cache) {
|
||||
/* We store the response for this request. It'll later become
|
||||
available to caches.match(event.request) calls, when looking
|
||||
for cached responses.
|
||||
*/
|
||||
cache.put(event.request, cacheCopy);
|
||||
})
|
||||
.then(function () {
|
||||
//console.log('WORKER: fetch response stored in cache.', event.request.url);
|
||||
});
|
||||
|
||||
// Return the response so that the promise is settled in fulfillment.
|
||||
return response;
|
||||
}
|
||||
|
||||
/* When this method is called, it means we were unable to produce a response
|
||||
from either the cache or the network. This is our opportunity to produce
|
||||
a meaningful response even when all else fails. It's the last chance, so
|
||||
you probably want to display a "Service Unavailable" view or a generic
|
||||
error response.
|
||||
*/
|
||||
function unableToResolve() {
|
||||
/* There's a couple of things we can do here.
|
||||
- Test the Accept header and then return one of the `offlineFundamentals`
|
||||
e.g: `return caches.match('/some/cached/image.png')`
|
||||
- You should also consider the origin. It's easier to decide what
|
||||
"unavailable" means for requests against your origins than for requests
|
||||
against a third party, such as an ad provider.
|
||||
- Generate a Response programmaticaly, as shown below, and return that.
|
||||
*/
|
||||
|
||||
//console.log('WORKER: fetch request failed in both cache and network.');
|
||||
|
||||
/* Here we're creating a response programmatically. The first parameter is the
|
||||
response body, and the second one defines the options for the response.
|
||||
*/
|
||||
return new Response('<h1>Service Unavailable</h1>', {
|
||||
status: 503,
|
||||
statusText: 'Service Unavailable',
|
||||
headers: new Headers({
|
||||
'Content-Type': 'text/html'
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
/* The activate event fires after a service worker has been successfully installed.
|
||||
It is most useful when phasing out an older version of a service worker, as at
|
||||
this point you know that the new worker was installed correctly. In this example,
|
||||
we delete old caches that don't match the version in the worker we just finished
|
||||
installing.
|
||||
*/
|
||||
self.addEventListener("activate", function (event) {
|
||||
/* Just like with the install event, event.waitUntil blocks activate on a promise.
|
||||
Activation will fail unless the promise is fulfilled.
|
||||
*/
|
||||
//console.log('WORKER: activate event in progress.');
|
||||
|
||||
event.waitUntil(
|
||||
caches
|
||||
/* This method returns a promise which will resolve to an array of available
|
||||
cache keys.
|
||||
*/
|
||||
.keys()
|
||||
.then(function (keys) {
|
||||
// We return a promise that settles when all outdated caches are deleted.
|
||||
return Promise.all(
|
||||
keys
|
||||
.filter(function (key) {
|
||||
// Filter by keys that don't start with the latest version prefix.
|
||||
return !key.startsWith(version);
|
||||
})
|
||||
.map(function (key) {
|
||||
/* Return a promise that's fulfilled
|
||||
when each outdated cache is deleted.
|
||||
*/
|
||||
return caches.delete(key);
|
||||
})
|
||||
);
|
||||
})
|
||||
.then(function () {
|
||||
//console.log('WORKER: activate completed.');
|
||||
})
|
||||
);
|
||||
});
|
20
examples/PWA-example/src/main.rs
Normal file
20
examples/PWA-example/src/main.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
// init debug tool for WebAssembly
|
||||
wasm_logger::init(wasm_logger::Config::default());
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
dioxus_web::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx! (
|
||||
div {
|
||||
style: "text-align: center;",
|
||||
h1 { "🌗 Dioxus 🚀" }
|
||||
h3 { "Frontend that scales." }
|
||||
p { "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust." }
|
||||
}
|
||||
))
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
|
@ -5,9 +7,20 @@ fn main() {
|
|||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx! { generic_child::<i32>{} })
|
||||
cx.render(rsx! { generic_child {
|
||||
data: 0i32
|
||||
} })
|
||||
}
|
||||
|
||||
fn generic_child<T>(cx: Scope) -> Element {
|
||||
cx.render(rsx! { div {} })
|
||||
#[derive(PartialEq, Props)]
|
||||
struct GenericChildProps<T: Display + PartialEq> {
|
||||
data: T,
|
||||
}
|
||||
|
||||
fn generic_child<T: Display + PartialEq>(cx: Scope<GenericChildProps<T>>) -> Element {
|
||||
let data = &cx.props.data;
|
||||
|
||||
cx.render(rsx! { div {
|
||||
"{data}"
|
||||
} })
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ fn app(cx: Scope) -> Element {
|
|||
onclick: move |_| {
|
||||
use rand::Rng;
|
||||
let mut rng = rand::thread_rng();
|
||||
val.set(rng.gen_range(1..6));
|
||||
val.set(rng.gen_range(1..=6));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,13 +276,12 @@ impl Writer<'_> {
|
|||
let start = location.start();
|
||||
let line_start = start.line - 1;
|
||||
|
||||
let this_line = self.src[line_start];
|
||||
|
||||
let beginning = if this_line.len() > start.column {
|
||||
this_line[..start.column].trim()
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let beginning = self
|
||||
.src
|
||||
.get(line_start)
|
||||
.filter(|this_line| this_line.len() > start.column)
|
||||
.map(|this_line| this_line[..start.column].trim())
|
||||
.unwrap_or_default();
|
||||
|
||||
beginning.is_empty()
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ lightningcss = "1.0.0-alpha.39"
|
|||
|
||||
rayon = "1.6.1"
|
||||
shipyard = { version = "0.6.2", features = ["proc", "std"], default-features = false }
|
||||
shipyard_hierarchy = "0.6.0"
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.5"
|
||||
|
|
|
@ -98,7 +98,8 @@ pub fn render<R: Driver>(
|
|||
let event_tx_clone = event_tx.clone();
|
||||
if !cfg.headless {
|
||||
std::thread::spawn(move || {
|
||||
let tick_rate = Duration::from_millis(1000);
|
||||
// Timeout after 10ms when waiting for events
|
||||
let tick_rate = Duration::from_millis(10);
|
||||
loop {
|
||||
if crossterm::event::poll(tick_rate).unwrap() {
|
||||
let evt = crossterm::event::read().unwrap();
|
||||
|
|
|
@ -45,13 +45,13 @@ pub fn Route<'a>(cx: Scope<'a, RouteProps<'a>>) -> Element {
|
|||
router_root.register_total_route(route_context.total_route, cx.scope_id());
|
||||
});
|
||||
|
||||
log::debug!("Checking Route: {:?}", cx.props.to);
|
||||
log::trace!("Checking Route: {:?}", cx.props.to);
|
||||
|
||||
if router_root.should_render(cx.scope_id()) {
|
||||
log::debug!("Route should render: {:?}", cx.scope_id());
|
||||
log::trace!("Route should render: {:?}", cx.scope_id());
|
||||
cx.render(rsx!(&cx.props.children))
|
||||
} else {
|
||||
log::debug!("Route should *not* render: {:?}", cx.scope_id());
|
||||
log::trace!("Route should *not* render: {:?}", cx.scope_id());
|
||||
cx.render(rsx!(()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,3 +25,6 @@ convert_case = "0.5.0"
|
|||
# default = ["html"]
|
||||
|
||||
# eventually more output options
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.2.1"
|
68
packages/rsx-rosetta/tests/simple.rs
Normal file
68
packages/rsx-rosetta/tests/simple.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use html_parser::Dom;
|
||||
|
||||
#[test]
|
||||
fn simple_elements() {
|
||||
let html = r#"
|
||||
<div>
|
||||
<div class="asd">hello world!</div>
|
||||
<div id="asd">hello world!</div>
|
||||
<div id="asd">hello world!</div>
|
||||
<div for="asd">hello world!</div>
|
||||
<div async="asd">hello world!</div>
|
||||
<div LargeThing="asd">hello world!</div>
|
||||
<ai-is-awesome>hello world!</ai-is-awesome>
|
||||
</div>
|
||||
"#
|
||||
.trim();
|
||||
|
||||
let dom = Dom::parse(html).unwrap();
|
||||
|
||||
let body = rsx_rosetta::rsx_from_html(&dom);
|
||||
|
||||
let out = dioxus_autofmt::write_block_out(body).unwrap();
|
||||
|
||||
let expected = r#"
|
||||
div {
|
||||
div { class: "asd", "hello world!" }
|
||||
div { id: "asd", "hello world!" }
|
||||
div { id: "asd", "hello world!" }
|
||||
div { r#for: "asd", "hello world!" }
|
||||
div { r#async: "asd", "hello world!" }
|
||||
div { large_thing: "asd", "hello world!" }
|
||||
ai_is_awesome { "hello world!" }
|
||||
}"#;
|
||||
pretty_assertions::assert_eq!(&out, &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deeply_nested() {
|
||||
let html = r#"
|
||||
<div>
|
||||
<div class="asd">
|
||||
<div class="asd">
|
||||
<div class="asd">
|
||||
<div class="asd">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"#
|
||||
.trim();
|
||||
|
||||
let dom = Dom::parse(html).unwrap();
|
||||
|
||||
let body = rsx_rosetta::rsx_from_html(&dom);
|
||||
|
||||
let out = dioxus_autofmt::write_block_out(body).unwrap();
|
||||
|
||||
let expected = r#"
|
||||
div {
|
||||
div { class: "asd",
|
||||
div { class: "asd",
|
||||
div { class: "asd", div { class: "asd" } }
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
pretty_assertions::assert_eq!(&out, &expected);
|
||||
}
|
|
@ -225,7 +225,7 @@ pub async fn run_with_props<T: 'static>(root: fn(Scope<T>) -> Element, root_prop
|
|||
websys_dom.mount();
|
||||
|
||||
loop {
|
||||
log::debug!("waiting for work");
|
||||
log::trace!("waiting for work");
|
||||
|
||||
// if virtualdom has nothing, wait for it to have something before requesting idle time
|
||||
// if there is work then this future resolves immediately.
|
||||
|
|
Loading…
Add table
Reference in a new issue