Add initial_value attribute & fix static special attribute handling (#1063)

* feat & fix: initial_value attribute, special attribute handling

* revision: rename js file

* fix: rustfmt

* fix: clippy

* fix: desktop not finding common.js

* fix: desktop failing to render

Missed a single ``this.SetAttributeInner`` as it was now ``setAttributeInner``
Javascript didn't even throw any errors about this smh

* revision: no need for match statement
This commit is contained in:
Miles Murgaw authored and GitHub committed 2023-06-04 11:29:34 -05:00
1 parent 0f684f0567
commit d09c92beda
9 files changed
+82 -18

No files matched your search

+7 -2
View File
@@ -1,4 +1,4 @@
use dioxus_interpreter_js::INTERPRETER_JS; use dioxus_interpreter_js::{COMMON_JS, INTERPRETER_JS};
use std::{ use std::{
borrow::Cow, borrow::Cow,
path::{Path, PathBuf}, path::{Path, PathBuf},
@@ -37,7 +37,7 @@ fn module_loader(root_name: &str) -> String {
); );
format!( format!(
r#" r#"
<script> <script type="module">
{js} {js}
let rootname = "{root_name}"; let rootname = "{root_name}";
@@ -84,6 +84,11 @@ pub(super) fn desktop_handler(
.header("Content-Type", "text/html") .header("Content-Type", "text/html")
.body(Cow::from(body)) .body(Cow::from(body))
.map_err(From::from); .map_err(From::from);
} else if request.uri().path() == "/common.js" {
return Response::builder()
.header("Content-Type", "text/javascript")
.body(Cow::from(COMMON_JS.as_bytes()))
.map_err(From::from);
} }
// Else, try to serve a file from the filesystem. // Else, try to serve a file from the filesystem.
+1
View File
@@ -1154,6 +1154,7 @@ builder_constructors! {
r#type: InputType "type", r#type: InputType "type",
// value: String, // value: String,
value: String volatile, value: String volatile,
initial_value: String DEFAULT,
}; };
/// Build a /// Build a
+1
View File
@@ -25,3 +25,4 @@ default = []
serialize = ["serde"] serialize = ["serde"]
web = ["wasm-bindgen", "js-sys", "web-sys"] web = ["wasm-bindgen", "js-sys", "web-sys"]
sledgehammer = ["wasm-bindgen", "js-sys", "web-sys", "sledgehammer_bindgen", "sledgehammer_utils"] sledgehammer = ["wasm-bindgen", "js-sys", "web-sys", "sledgehammer_bindgen", "sledgehammer_utils"]
minimal_bindings = []
+39
View File
@@ -0,0 +1,39 @@
export function setAttributeInner(node, field, value, ns) {
const name = field;
if (ns === "style") {
// ????? why do we need to do this
if (node.style === undefined) {
node.style = {};
}
node.style[name] = value;
} else if (ns != null && ns != undefined) {
node.setAttributeNS(ns, name, value);
} else {
switch (name) {
case "value":
if (value !== node.value) {
node.value = value;
}
break;
case "initial_value":
node.defaultValue = value;
break;
case "checked":
node.checked = value === "true" || value === true;
break;
case "selected":
node.selected = value === "true" || value === true;
break;
case "dangerous_inner_html":
node.innerHTML = value;
break;
default:
// https://github.com/facebook/react/blob/8b88ac2592c5f555f315f9440cbb665dd1e7457a/packages/react-dom/src/shared/DOMProperty.js#L352-L364
if (value === "false" && bool_attrs.hasOwnProperty(name)) {
node.removeAttribute(name);
} else {
node.setAttribute(name, value);
}
}
}
}
+9 -4
View File
@@ -1,3 +1,5 @@
import { setAttributeInner } from "./common.js";
class ListenerMap { class ListenerMap {
constructor(root) { constructor(root) {
// bubbling events can listen at the root element // bubbling events can listen at the root element
@@ -153,10 +155,10 @@ class Interpreter {
this.RemoveAttribute(id, field, ns); this.RemoveAttribute(id, field, ns);
} else { } else {
const node = this.nodes[id]; const node = this.nodes[id];
this.SetAttributeInner(node, field, value, ns); setAttributeInner(node, field, value, ns);
} }
} }
SetAttributeInner(node, field, value, ns) { /*SetAttributeInner(node, field, value, ns) {
const name = field; const name = field;
if (ns === "style") { if (ns === "style") {
// ????? why do we need to do this // ????? why do we need to do this
@@ -173,6 +175,9 @@ class Interpreter {
node.value = value; node.value = value;
} }
break; break;
case "initial_value":
node.defaultValue = value;
break;
case "checked": case "checked":
node.checked = value === "true" || value === true; node.checked = value === "true" || value === true;
break; break;
@@ -191,7 +196,7 @@ class Interpreter {
} }
} }
} }
} }*/
RemoveAttribute(root, field, ns) { RemoveAttribute(root, field, ns) {
const name = field; const name = field;
const node = this.nodes[root]; const node = this.nodes[root];
@@ -291,7 +296,7 @@ class Interpreter {
for (let attr of node.attrs) { for (let attr of node.attrs) {
if (attr.type == "Static") { if (attr.type == "Static") {
this.SetAttributeInner(el, attr.name, attr.value, attr.namespace); setAttributeInner(el, attr.name, attr.value, attr.namespace);
} }
} }
+11
View File
@@ -1,4 +1,5 @@
pub static INTERPRETER_JS: &str = include_str!("./interpreter.js"); pub static INTERPRETER_JS: &str = include_str!("./interpreter.js");
pub static COMMON_JS: &str = include_str!("./common.js");
#[cfg(feature = "sledgehammer")] #[cfg(feature = "sledgehammer")]
mod sledgehammer_bindings; mod sledgehammer_bindings;
@@ -10,3 +11,13 @@ mod bindings;
#[cfg(feature = "web")] #[cfg(feature = "web")]
pub use bindings::Interpreter; pub use bindings::Interpreter;
// Common bindings for minimal usage.
#[cfg(feature = "minimal_bindings")]
pub mod minimal_bindings {
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
#[wasm_bindgen(module = "/src/common.js")]
extern "C" {
pub fn setAttributeInner(node: JsValue, name: &str, value: JsValue, ns: Option<&str>);
}
}
@@ -74,6 +74,9 @@ mod js {
node.value = value; node.value = value;
} }
break; break;
case "initial_value":
node.defaultValue = value;
break;
case "checked": case "checked":
node.checked = value === "true"; node.checked = value === "true";
break; break;
+2 -1
View File
@@ -14,7 +14,8 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] } dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] }
dioxus-html = { path = "../html", version = "^0.3.0", features = ["wasm-bind"] } dioxus-html = { path = "../html", version = "^0.3.0", features = ["wasm-bind"] }
dioxus-interpreter-js = { path = "../interpreter", version = "^0.3.0", features = [ dioxus-interpreter-js = { path = "../interpreter", version = "^0.3.0", features = [
"sledgehammer" "sledgehammer",
"minimal_bindings",
] } ] }
js-sys = "0.3.56" js-sys = "0.3.56"
+9 -11
View File
@@ -11,13 +11,13 @@ use dioxus_core::{
BorrowedAttributeValue, ElementId, Mutation, Template, TemplateAttribute, TemplateNode, BorrowedAttributeValue, ElementId, Mutation, Template, TemplateAttribute, TemplateNode,
}; };
use dioxus_html::{event_bubbles, CompositionData, FileEngine, FormData, MountedData}; use dioxus_html::{event_bubbles, CompositionData, FileEngine, FormData, MountedData};
use dioxus_interpreter_js::{get_node, save_template, Channel}; use dioxus_interpreter_js::{get_node, minimal_bindings, save_template, Channel};
use futures_channel::mpsc; use futures_channel::mpsc;
use js_sys::Array; use js_sys::Array;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use std::{any::Any, rc::Rc, sync::Arc}; use std::{any::Any, rc::Rc, sync::Arc};
use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast}; use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast, JsValue};
use web_sys::{console, Document, Element, Event, HtmlElement}; use web_sys::{console, Document, Element, Event};
use crate::{file_engine::WebFileEngine, Config}; use crate::{file_engine::WebFileEngine, Config};
@@ -135,14 +135,12 @@ impl WebsysDom {
namespace, namespace,
} = attr } = attr
{ {
match namespace { minimal_bindings::setAttributeInner(
Some(ns) if *ns == "style" => { el.clone().into(),
el.dyn_ref::<HtmlElement>() name,
.map(|f| f.style().set_property(name, value)); JsValue::from_str(value),
} *namespace,
Some(ns) => el.set_attribute_ns(Some(ns), name, value).unwrap(), );
None => el.set_attribute(name, value).unwrap(),
}
} }
} }
for child in *children { for child in *children {