Merge branch 'upstream' into disable-browser-shortcuts
This commit is contained in:
commit
bc014f7107
7 files changed
+113
-12
No files matched your search
@@ -0,0 +1,36 @@
|
||||
//! Comparison example with leptos' counter example
|
||||
//! https://github.com/leptos-rs/leptos/blob/main/examples/counters/src/lib.rs
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let counters = use_state(cx, || vec![0, 0, 0]);
|
||||
let sum: usize = counters.iter().copied().sum();
|
||||
|
||||
render! {
|
||||
div {
|
||||
button { onclick: move |_| counters.make_mut().push(0), "Add counter" }
|
||||
button { onclick: move |_| { counters.make_mut().pop(); }, "Remove counter" }
|
||||
p { "Total: {sum}" }
|
||||
for (i, counter) in counters.iter().enumerate() {
|
||||
li {
|
||||
button { onclick: move |_| counters.make_mut()[i] -= 1, "-1" }
|
||||
input {
|
||||
value: "{counter}",
|
||||
oninput: move |e| {
|
||||
if let Ok(value) = e.value.parse::<usize>() {
|
||||
counters.make_mut()[i] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
button { onclick: move |_| counters.make_mut()[i] += 1, "+1" }
|
||||
button { onclick: move |_| { counters.make_mut().remove(i); }, "x" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,8 +36,8 @@ use tao::{
|
||||
};
|
||||
pub use wry;
|
||||
pub use wry::application as tao;
|
||||
use wry::application::window::WindowId;
|
||||
use wry::webview::WebView;
|
||||
use wry::{application::window::WindowId, webview::WebContext};
|
||||
|
||||
/// Launch the WebView and run the event loop.
|
||||
///
|
||||
@@ -281,7 +281,7 @@ fn create_new_window(
|
||||
event_handlers: &WindowEventHandlers,
|
||||
shortcut_manager: ShortcutRegistry,
|
||||
) -> WebviewHandler {
|
||||
let webview = webview::build(&mut cfg, event_loop, proxy.clone());
|
||||
let (webview, web_context) = webview::build(&mut cfg, event_loop, proxy.clone());
|
||||
|
||||
dom.base_scope().provide_context(DesktopContext::new(
|
||||
webview.clone(),
|
||||
@@ -299,6 +299,7 @@ fn create_new_window(
|
||||
webview,
|
||||
dom,
|
||||
waker: waker::tao_waker(proxy, id),
|
||||
web_context,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +307,7 @@ struct WebviewHandler {
|
||||
dom: VirtualDom,
|
||||
webview: Rc<wry::webview::WebView>,
|
||||
waker: Waker,
|
||||
web_context: WebContext,
|
||||
}
|
||||
|
||||
/// Poll the virtualdom until it's pending
|
||||
|
||||
@@ -7,13 +7,13 @@ use tao::event_loop::{EventLoopProxy, EventLoopWindowTarget};
|
||||
pub use wry;
|
||||
pub use wry::application as tao;
|
||||
use wry::application::window::Window;
|
||||
use wry::webview::{WebView, WebViewBuilder};
|
||||
use wry::webview::{WebContext, WebView, WebViewBuilder};
|
||||
|
||||
pub fn build(
|
||||
cfg: &mut Config,
|
||||
event_loop: &EventLoopWindowTarget<UserWindowEvent>,
|
||||
proxy: EventLoopProxy<UserWindowEvent>,
|
||||
) -> Rc<WebView> {
|
||||
) -> (Rc<WebView>, WebContext) {
|
||||
let builder = cfg.window.clone();
|
||||
let window = builder.build(event_loop).unwrap();
|
||||
let file_handler = cfg.file_drop_handler.take();
|
||||
@@ -33,6 +33,8 @@ pub fn build(
|
||||
));
|
||||
}
|
||||
|
||||
let mut web_context = WebContext::new(cfg.data_dir.clone());
|
||||
|
||||
let mut webview = WebViewBuilder::new(window)
|
||||
.unwrap()
|
||||
.with_transparent(cfg.window.window.transparent)
|
||||
@@ -52,7 +54,8 @@ pub fn build(
|
||||
.as_ref()
|
||||
.map(|handler| handler(window, evet))
|
||||
.unwrap_or_default()
|
||||
});
|
||||
})
|
||||
.with_web_context(&mut web_context);
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
@@ -89,5 +92,5 @@ pub fn build(
|
||||
webview = webview.with_devtools(true);
|
||||
}
|
||||
|
||||
Rc::new(webview.build().unwrap())
|
||||
(Rc::new(webview.build().unwrap()), web_context)
|
||||
}
|
||||
@@ -23,6 +23,8 @@ pub enum Segment {
|
||||
// This will be true if there are static styles
|
||||
inside_style_tag: bool,
|
||||
},
|
||||
/// A marker for where to insert a dynamic inner html
|
||||
InnerHtmlMarker,
|
||||
}
|
||||
|
||||
impl std::fmt::Write for StringChain {
|
||||
@@ -69,6 +71,9 @@ impl StringCache {
|
||||
write!(chain, "<{tag}")?;
|
||||
// we need to collect the styles and write them at the end
|
||||
let mut styles = Vec::new();
|
||||
// we need to collect the inner html and write it at the end
|
||||
let mut inner_html = None;
|
||||
// we need to keep track of if we have dynamic attrs to know if we need to insert a style and inner_html marker
|
||||
let mut has_dynamic_attrs = false;
|
||||
for attr in *attrs {
|
||||
match attr {
|
||||
@@ -77,7 +82,9 @@ impl StringCache {
|
||||
value,
|
||||
namespace,
|
||||
} => {
|
||||
if let Some("style") = namespace {
|
||||
if *name == "dangerous_inner_html" {
|
||||
inner_html = Some(value);
|
||||
} else if let Some("style") = namespace {
|
||||
styles.push((name, value));
|
||||
} else {
|
||||
write!(chain, " {name}=\"{value}\"")?;
|
||||
@@ -110,6 +117,13 @@ impl StringCache {
|
||||
write!(chain, "/>")?;
|
||||
} else {
|
||||
write!(chain, ">")?;
|
||||
// Write the static inner html, or insert a marker if dynamic inner html is possible
|
||||
if let Some(inner_html) = inner_html {
|
||||
chain.write_str(inner_html)?;
|
||||
} else if has_dynamic_attrs {
|
||||
chain.segments.push(Segment::InnerHtmlMarker);
|
||||
}
|
||||
|
||||
for child in *children {
|
||||
Self::recurse(child, cur_path, root_idx, chain)?;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ impl Renderer {
|
||||
.or_insert_with(|| Rc::new(StringCache::from_template(template).unwrap()))
|
||||
.clone();
|
||||
|
||||
let mut inner_html = None;
|
||||
|
||||
// We need to keep track of the dynamic styles so we can insert them into the right place
|
||||
let mut accumulated_dynamic_styles = Vec::new();
|
||||
|
||||
@@ -77,7 +79,9 @@ impl Renderer {
|
||||
match segment {
|
||||
Segment::Attr(idx) => {
|
||||
let attr = &template.dynamic_attrs[*idx];
|
||||
if attr.namespace == Some("style") {
|
||||
if attr.name == "dangerous_inner_html" {
|
||||
inner_html = Some(attr);
|
||||
} else if attr.namespace == Some("style") {
|
||||
accumulated_dynamic_styles.push(attr);
|
||||
} else {
|
||||
match attr.value {
|
||||
@@ -165,6 +169,19 @@ impl Renderer {
|
||||
accumulated_dynamic_styles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Segment::InnerHtmlMarker => {
|
||||
if let Some(inner_html) = inner_html.take() {
|
||||
let inner_html = &inner_html.value;
|
||||
match inner_html {
|
||||
AttributeValue::Text(value) => write!(buf, "{}", value)?,
|
||||
AttributeValue::Bool(value) => write!(buf, "{}", value)?,
|
||||
AttributeValue::Float(f) => write!(buf, "{}", f)?,
|
||||
AttributeValue::Int(i) => write!(buf, "{}", i)?,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +225,9 @@ fn to_string_works() {
|
||||
StyleMarker {
|
||||
inside_style_tag: false,
|
||||
},
|
||||
PreRendered(">Hello world 1 -->".into(),),
|
||||
PreRendered(">".into()),
|
||||
InnerHtmlMarker,
|
||||
PreRendered("Hello world 1 -->".into(),),
|
||||
Node(0,),
|
||||
PreRendered(
|
||||
"<-- Hello world 2<div>nest 1</div><div></div><div>nest 2</div>".into(),
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn static_inner_html() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
render! { div { dangerous_inner_html: "<div>1234</div>" } }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
_ = dom.rebuild();
|
||||
|
||||
assert_eq!(dioxus_ssr::render(&dom), r#"<div><div>1234</div></div>"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dynamic_inner_html() {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let inner_html = "<div>1234</div>";
|
||||
render! { div { dangerous_inner_html: "{inner_html}" } }
|
||||
}
|
||||
|
||||
let mut dom = VirtualDom::new(app);
|
||||
_ = dom.rebuild();
|
||||
|
||||
assert_eq!(dioxus_ssr::render(&dom), r#"<div><div>1234</div></div>"#);
|
||||
}
|
||||
@@ -49,15 +49,16 @@ impl Config {
|
||||
|
||||
/// Set the name of the element that Dioxus will use as the root.
|
||||
///
|
||||
/// This is akint to calling React.render() on the element with the specified name.
|
||||
/// This is akin to calling React.render() on the element with the specified name.
|
||||
pub fn rootname(mut self, name: impl Into<String>) -> Self {
|
||||
self.rootname = name.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the name of the element that Dioxus will use as the root.
|
||||
/// Sets a string cache for wasm bindgen to [intern](https://docs.rs/wasm-bindgen/0.2.84/wasm_bindgen/fn.intern.html). This can help reduce the time it takes for wasm bindgen to pass
|
||||
/// strings from rust to javascript. This can significantly improve pefromance when passing strings to javascript, but can have a negative impact on startup time.
|
||||
///
|
||||
/// This is akint to calling React.render() on the element with the specified name.
|
||||
/// > Currently this cache is only used when creating static elements and attributes.
|
||||
pub fn with_string_cache(mut self, cache: Vec<String>) -> Self {
|
||||
self.cached_strings = cache;
|
||||
self
|
||||
|
||||
Reference in new issue
Block a user