mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-10 22:54:12 +00:00
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:
parent
0f684f0567
commit
d09c92beda
9 changed files with 82 additions and 18 deletions
|
@ -1,4 +1,4 @@
|
|||
use dioxus_interpreter_js::INTERPRETER_JS;
|
||||
use dioxus_interpreter_js::{COMMON_JS, INTERPRETER_JS};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -37,7 +37,7 @@ fn module_loader(root_name: &str) -> String {
|
|||
);
|
||||
format!(
|
||||
r#"
|
||||
<script>
|
||||
<script type="module">
|
||||
{js}
|
||||
|
||||
let rootname = "{root_name}";
|
||||
|
@ -84,6 +84,11 @@ pub(super) fn desktop_handler(
|
|||
.header("Content-Type", "text/html")
|
||||
.body(Cow::from(body))
|
||||
.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.
|
||||
|
|
|
@ -1154,6 +1154,7 @@ builder_constructors! {
|
|||
r#type: InputType "type",
|
||||
// value: String,
|
||||
value: String volatile,
|
||||
initial_value: String DEFAULT,
|
||||
};
|
||||
|
||||
/// Build a
|
||||
|
|
|
@ -25,3 +25,4 @@ default = []
|
|||
serialize = ["serde"]
|
||||
web = ["wasm-bindgen", "js-sys", "web-sys"]
|
||||
sledgehammer = ["wasm-bindgen", "js-sys", "web-sys", "sledgehammer_bindgen", "sledgehammer_utils"]
|
||||
minimal_bindings = []
|
||||
|
|
39
packages/interpreter/src/common.js
Normal file
39
packages/interpreter/src/common.js
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { setAttributeInner } from "./common.js";
|
||||
|
||||
class ListenerMap {
|
||||
constructor(root) {
|
||||
// bubbling events can listen at the root element
|
||||
|
@ -153,10 +155,10 @@ class Interpreter {
|
|||
this.RemoveAttribute(id, field, ns);
|
||||
} else {
|
||||
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;
|
||||
if (ns === "style") {
|
||||
// ????? why do we need to do this
|
||||
|
@ -173,6 +175,9 @@ class Interpreter {
|
|||
node.value = value;
|
||||
}
|
||||
break;
|
||||
case "initial_value":
|
||||
node.defaultValue = value;
|
||||
break;
|
||||
case "checked":
|
||||
node.checked = value === "true" || value === true;
|
||||
break;
|
||||
|
@ -191,7 +196,7 @@ class Interpreter {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
RemoveAttribute(root, field, ns) {
|
||||
const name = field;
|
||||
const node = this.nodes[root];
|
||||
|
@ -291,7 +296,7 @@ class Interpreter {
|
|||
|
||||
for (let attr of node.attrs) {
|
||||
if (attr.type == "Static") {
|
||||
this.SetAttributeInner(el, attr.name, attr.value, attr.namespace);
|
||||
setAttributeInner(el, attr.name, attr.value, attr.namespace);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub static INTERPRETER_JS: &str = include_str!("./interpreter.js");
|
||||
pub static COMMON_JS: &str = include_str!("./common.js");
|
||||
|
||||
#[cfg(feature = "sledgehammer")]
|
||||
mod sledgehammer_bindings;
|
||||
|
@ -10,3 +11,13 @@ mod bindings;
|
|||
|
||||
#[cfg(feature = "web")]
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case "initial_value":
|
||||
node.defaultValue = value;
|
||||
break;
|
||||
case "checked":
|
||||
node.checked = value === "true";
|
||||
break;
|
||||
|
|
|
@ -14,7 +14,8 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
|
|||
dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] }
|
||||
dioxus-html = { path = "../html", version = "^0.3.0", features = ["wasm-bind"] }
|
||||
dioxus-interpreter-js = { path = "../interpreter", version = "^0.3.0", features = [
|
||||
"sledgehammer"
|
||||
"sledgehammer",
|
||||
"minimal_bindings",
|
||||
] }
|
||||
|
||||
js-sys = "0.3.56"
|
||||
|
|
|
@ -11,13 +11,13 @@ use dioxus_core::{
|
|||
BorrowedAttributeValue, ElementId, Mutation, Template, TemplateAttribute, TemplateNode,
|
||||
};
|
||||
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 js_sys::Array;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{any::Any, rc::Rc, sync::Arc};
|
||||
use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast};
|
||||
use web_sys::{console, Document, Element, Event, HtmlElement};
|
||||
use wasm_bindgen::{closure::Closure, prelude::wasm_bindgen, JsCast, JsValue};
|
||||
use web_sys::{console, Document, Element, Event};
|
||||
|
||||
use crate::{file_engine::WebFileEngine, Config};
|
||||
|
||||
|
@ -135,14 +135,12 @@ impl WebsysDom {
|
|||
namespace,
|
||||
} = attr
|
||||
{
|
||||
match namespace {
|
||||
Some(ns) if *ns == "style" => {
|
||||
el.dyn_ref::<HtmlElement>()
|
||||
.map(|f| f.style().set_property(name, value));
|
||||
}
|
||||
Some(ns) => el.set_attribute_ns(Some(ns), name, value).unwrap(),
|
||||
None => el.set_attribute(name, value).unwrap(),
|
||||
}
|
||||
minimal_bindings::setAttributeInner(
|
||||
el.clone().into(),
|
||||
name,
|
||||
JsValue::from_str(value),
|
||||
*namespace,
|
||||
);
|
||||
}
|
||||
}
|
||||
for child in *children {
|
||||
|
|
Loading…
Reference in a new issue