Merge branch 'upstream' into disable-browser-shortcuts

This commit is contained in:
Evan Almloff committed 2023-04-12 09:09:36 -05:00
commit bc014f7107
7 files changed
+113 -12

No files matched your search

+36
View File
@@ -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" }
}
}
}
}
}
+4 -2
View File
@@ -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 -4
View File
@@ -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)
}
+15 -1
View File
@@ -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)?;
}
+21 -2
View File
@@ -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 --&gt;".into(),),
PreRendered(">".into()),
InnerHtmlMarker,
PreRendered("Hello world 1 --&gt;".into(),),
Node(0,),
PreRendered(
"&lt;-- Hello world 2<div>nest 1</div><div></div><div>nest 2</div>".into(),
+26
View File
@@ -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>"#);
}
+4 -3
View File
@@ -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