Merge branch 'master' into fix-links-liveview

This commit is contained in:
Evan Almloff committed 2023-05-24 07:36:16 -05:00
commit 77275d40c1
27 files changed
+217 -243

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "dioxus-core"
version = "0.3.2"
version = "0.3.3"
authors = ["Jonathan Kelley"]
edition = "2018"
description = "Core functionality for Dioxus - a concurrent renderer-agnostic Virtual DOM for interactive user experiences"
+4 -1
View File
@@ -4,7 +4,8 @@ use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub(crate) struct FileDiologRequest {
accept: String,
#[serde(default)]
accept: Option<String>,
multiple: bool,
pub event: String,
pub target: usize,
@@ -16,6 +17,8 @@ pub(crate) fn get_file_event(request: &FileDiologRequest) -> Vec<PathBuf> {
let filters: Vec<_> = request
.accept
.as_deref()
.unwrap_or_default()
.split(',')
.filter_map(|s| Filters::from_str(s).ok())
.collect();
+8 -8
View File
@@ -15,12 +15,12 @@ fn module_loader(root_name: &str) -> String {
let inputs = document.querySelectorAll("input");
for (let input of inputs) {
if (!input.getAttribute("data-dioxus-file-listener")) {
input.setAttribute("data-dioxus-file-listener", true);
input.addEventListener("click", (event) => {
let target = event.target;
// prevent file inputs from opening the file dialog on click
const type = target.getAttribute("type");
if (type === "file") {
// prevent file inputs from opening the file dialog on click
const type = input.getAttribute("type");
if (type === "file") {
input.setAttribute("data-dioxus-file-listener", true);
input.addEventListener("click", (event) => {
let target = event.target;
let target_id = find_real_id(target);
if (target_id !== null) {
const send = (event_name) => {
@@ -30,8 +30,8 @@ fn module_loader(root_name: &str) -> String {
send("change&input");
}
event.preventDefault();
}
});
});
}
}
}"#,
);
@@ -1,67 +0,0 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_tui::Config;
fn main() {
dioxus_tui::launch_cfg(app, Config::default());
}
#[derive(Props, PartialEq)]
struct QuadrentProps {
color: String,
text: String,
}
fn Quadrant(cx: Scope<QuadrentProps>) -> Element {
cx.render(rsx! {
div {
border_width: "1px",
width: "50%",
height: "100%",
background_color: "{cx.props.color}",
justify_content: "center",
align_items: "center",
"{cx.props.text}"
}
})
}
fn app(cx: Scope) -> Element {
cx.render(rsx! {
div {
width: "100%",
height: "100%",
flex_direction: "column",
div {
width: "100%",
height: "50%",
flex_direction: "row",
Quadrant{
color: "red".to_string(),
text: "[A]".to_string()
},
Quadrant{
color: "black".to_string(),
text: "[B]".to_string()
}
}
div {
width: "100%",
height: "50%",
flex_direction: "row",
Quadrant{
color: "green".to_string(),
text: "[C]".to_string()
},
Quadrant{
color: "blue".to_string(),
text: "[D]".to_string()
}
}
}
})
}
+39 -32
View File
@@ -1,7 +1,31 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_tui::Config;
fn main() {
dioxus_tui::launch(app);
dioxus_tui::launch_cfg(app, Config::default());
}
#[derive(Props, PartialEq)]
struct QuadrentProps {
color: String,
text: String,
}
fn Quadrant(cx: Scope<QuadrentProps>) -> Element {
cx.render(rsx! {
div {
border_width: "1px",
width: "50%",
height: "100%",
background_color: "{cx.props.color}",
justify_content: "center",
align_items: "center",
"{cx.props.text}"
}
})
}
fn app(cx: Scope) -> Element {
@@ -15,22 +39,13 @@ fn app(cx: Scope) -> Element {
width: "100%",
height: "50%",
flex_direction: "row",
div {
border_width: "1px",
width: "50%",
height: "100%",
background_color: "red",
justify_content: "center",
align_items: "center",
"[A]"
}
div {
width: "50%",
height: "100%",
background_color: "black",
justify_content: "center",
align_items: "center",
"[B]"
Quadrant{
color: "red".to_string(),
text: "[A]".to_string()
},
Quadrant{
color: "black".to_string(),
text: "[B]".to_string()
}
}
@@ -38,21 +53,13 @@ fn app(cx: Scope) -> Element {
width: "100%",
height: "50%",
flex_direction: "row",
div {
width: "50%",
height: "100%",
background_color: "green",
justify_content: "center",
align_items: "center",
"[C]"
}
div {
width: "50%",
height: "100%",
background_color: "blue",
justify_content: "center",
align_items: "center",
"[D]"
Quadrant{
color: "green".to_string(),
text: "[C]".to_string()
},
Quadrant{
color: "blue".to_string(),
text: "[D]".to_string()
}
}
}
+4
View File
@@ -34,6 +34,10 @@ use std::future::Future;
/// don't care about actions in your app being synchronized, you can use [`use_callback`]
/// hook to spawn multiple tasks and run them concurrently.
///
/// ### Notice
/// In order to use ``rx.next().await``, you will need to extend the ``Stream`` trait (used by ``UnboundedReceiver``)
/// by adding the ``futures-util`` crate as a dependency and adding ``StreamExt`` into scope via ``use futures_util::stream::StreamExt;``
///
/// ## Example
///
/// ```rust, ignore
+5
View File
@@ -359,6 +359,11 @@ builder_constructors! {
/// element.
header None {};
/// Build a
/// [`<hgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup)
/// element.
hgroup None {};
/// Build a
/// [`<h1>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1)
/// element.
+5 -1
View File
@@ -14,7 +14,11 @@ pub struct FormData {
#[cfg_attr(
feature = "serialize",
serde(skip_serializing, deserialize_with = "deserialize_file_engine")
serde(
default,
skip_serializing,
deserialize_with = "deserialize_file_engine"
)
)]
pub files: Option<std::sync::Arc<dyn FileEngine>>,
}
+31 -117
View File
@@ -353,105 +353,9 @@ class Interpreter {
case "NewEventListener":
let bubbles = event_bubbles(edit.name);
// this handler is only provided on desktop implementations since this
// method is not used by the web implementation
let handler = (event) => {
let target = event.target;
if (target != null) {
let realId = target.getAttribute(`data-dioxus-id`);
let shouldPreventDefault = target.getAttribute(
`dioxus-prevent-default`
);
if (event.type === "click") {
// todo call prevent default if it's the right type of event
if (this.config.intercept_link_redirects) {
let a_element = target.closest("a");
if (a_element != null) {
event.preventDefault();
if (
shouldPreventDefault !== `onclick` &&
a_element.getAttribute(`dioxus-prevent-default`) !==
`onclick`
) {
const href = a_element.getAttribute("href");
if (href !== "" && href !== null && href !== undefined) {
window.ipc.postMessage(
serializeIpcMessage("browser_open", { href })
);
}
}
}
}
// also prevent buttons from submitting
if (target.tagName === "BUTTON" && event.type == "submit") {
event.preventDefault();
}
}
// walk the tree to find the real element
while (realId == null) {
// we've reached the root we don't want to send an event
if (target.parentElement === null) {
return;
}
target = target.parentElement;
realId = target.getAttribute(`data-dioxus-id`);
}
shouldPreventDefault = target.getAttribute(
`dioxus-prevent-default`
);
let contents = serialize_event(event);
if (shouldPreventDefault === `on${event.type}`) {
event.preventDefault();
}
if (event.type === "submit") {
event.preventDefault();
}
if (
target.tagName === "FORM" &&
(event.type === "submit" || event.type === "input")
) {
for (let x = 0; x < target.elements.length; x++) {
let element = target.elements[x];
let name = element.getAttribute("name");
if (name != null) {
if (element.getAttribute("type") === "checkbox") {
// @ts-ignore
contents.values[name] = element.checked ? "true" : "false";
} else if (element.getAttribute("type") === "radio") {
if (element.checked) {
contents.values[name] = element.value;
}
} else {
// @ts-ignore
contents.values[name] =
element.value ?? element.textContent;
}
}
}
}
if (realId === null) {
return;
}
window.ipc.postMessage(
serializeIpcMessage("user_event", {
name: edit.name,
element: parseInt(realId),
data: contents,
bubbles,
})
);
}
};
this.NewEventListener(edit.name, edit.id, bubbles, handler);
this.NewEventListener(edit.name, edit.id, bubbles, (event) => {
handler(event, edit.name, bubbles, this.config);
});
break;
}
}
@@ -459,25 +363,34 @@ class Interpreter {
// this handler is only provided on the desktop and liveview implementations since this
// method is not used by the web implementation
function handler(event, name, bubbles) {
function handler(event, name, bubbles, config) {
let target = event.target;
if (target != null) {
let shouldPreventDefault = target.getAttribute(`dioxus-prevent-default`);
let preventDefaultRequests = target.getAttribute(`dioxus-prevent-default`);
if (event.type === "click") {
// Prevent redirects from links
let a_element = target.closest("a");
if (a_element != null) {
event.preventDefault();
if (
shouldPreventDefault !== `onclick` &&
a_element.getAttribute(`dioxus-prevent-default`) !== `onclick`
) {
const href = a_element.getAttribute("href");
if (href !== "" && href !== null && href !== undefined) {
window.ipc.postMessage(
serializeIpcMessage("browser_open", { href })
);
// todo call prevent default if it's the right type of event
if (config.intercept_link_redirects) {
let a_element = target.closest("a");
if (a_element != null) {
event.preventDefault();
let elementShouldPreventDefault =
preventDefaultRequests && preventDefaultRequests.includes(`onclick`);
let aElementShouldPreventDefault = a_element.getAttribute(
`dioxus-prevent-default`
);
let linkShouldPreventDefault =
aElementShouldPreventDefault &&
aElementShouldPreventDefault.includes(`onclick`);
if (!elementShouldPreventDefault && !linkShouldPreventDefault) {
const href = a_element.getAttribute("href");
if (href !== "" && href !== null && href !== undefined) {
window.ipc.postMessage(
serializeIpcMessage("browser_open", { href })
);
}
}
}
}
@@ -490,9 +403,10 @@ function handler(event, name, bubbles) {
const realId = find_real_id(target);
shouldPreventDefault = target.getAttribute(`dioxus-prevent-default`);
if (shouldPreventDefault === `on${event.type}`) {
if (
preventDefaultRequests &&
preventDefaultRequests.includes(`on${event.type}`)
) {
event.preventDefault();
}
+1 -1
View File
@@ -178,7 +178,7 @@ impl<'a> TreeMut for TreeMutView<'a> {
fn set_height(tree: &mut TreeMutView<'_>, node: NodeId, height: u16) {
let children = {
let mut node_data_mut = &mut tree.1;
let mut node = (&mut node_data_mut).get(node).unwrap();
let node = (&mut node_data_mut).get(node).unwrap();
node.height = height;
node.children.clone()
};
File renamed without changes.
+1 -1
View File
@@ -26,7 +26,7 @@ impl<'a> RinkBuffer<'a> {
// panic!("({x}, {y}) is not in {area:?}");
return;
}
let mut cell = self.buf.get_mut(x, y);
let cell = self.buf.get_mut(x, y);
cell.bg = convert(self.cfg.rendering_mode, new.bg.blend(cell.bg));
if new.symbol.is_empty() {
if !cell.symbol.is_empty() {
File renamed without changes.
+8 -4
View File
@@ -55,13 +55,17 @@ impl WebsysDom {
let element = walk_event_for_id(event);
let bubbles = dioxus_html::event_bubbles(name.as_str());
if let Some((element, target)) = element {
if target
if let Some(prevent_requests) = target
.get_attribute("dioxus-prevent-default")
.as_deref()
.map(|f| f.trim_start_matches("on"))
== Some(&name)
.map(|f| f.split_whitespace())
{
event.prevent_default();
if prevent_requests
.map(|f| f.trim_start_matches("on"))
.any(|f| f == name)
{
event.prevent_default();
}
}
let data = virtual_event_from_websys_event(event.clone(), target);