Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix form inputs, form submits navigating, file drop, multiple root elements #1974

Merged
merged 45 commits into from
Mar 7, 2024
Merged
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
53cafef
wip: add tests and slightly refactor interpreter code
jkelleyrtp Feb 24, 2024
7f60010
set up a typescript pipeline for interpreter
jkelleyrtp Feb 24, 2024
b5447c1
extend interpreter base class with platform methods
jkelleyrtp Feb 27, 2024
206a482
Merge branch 'main' into jk/fix-form-inputs
jkelleyrtp Feb 27, 2024
bdacca0
use this. on the unified bindings
jkelleyrtp Feb 27, 2024
4b64894
Add proper bundling to tsc
jkelleyrtp Feb 28, 2024
f447f01
Commit js
jkelleyrtp Feb 28, 2024
774fba8
track the configs too
jkelleyrtp Feb 28, 2024
925d061
add glue to webonly interpreter
jkelleyrtp Feb 28, 2024
f196514
change serialization
jkelleyrtp Feb 28, 2024
8a969a2
make interpreter extend the interpreter core class
ealmloff Feb 28, 2024
0ff0eb7
Use the platform as the base interpreter instead of trying to extend it
jkelleyrtp Mar 1, 2024
199173a
fix navigating when files are dropped
jkelleyrtp Mar 2, 2024
22266cc
Switch to bun, clean up web implementation
jkelleyrtp Mar 4, 2024
16b38e3
Merge branch 'main' into jk/fix-form-inputs
jkelleyrtp Mar 5, 2024
b751674
Web works with the js structure
jkelleyrtp Mar 5, 2024
44833c4
Merge branch 'main' into jk/fix-form-inputs
jkelleyrtp Mar 5, 2024
56a3657
clean up native js more
jkelleyrtp Mar 5, 2024
403e8e2
Clean up file uploads in desktop/liveview, remove minify
jkelleyrtp Mar 5, 2024
78d1653
wip: native file handles when dropping 🎉
jkelleyrtp Mar 5, 2024
624e58b
native file drop
jkelleyrtp Mar 5, 2024
39d6580
use git version of sledgehammer
jkelleyrtp Mar 5, 2024
4b2e426
clippy, and don't hash invisible files for ts generation
jkelleyrtp Mar 6, 2024
45b8243
attempt fix on inter
jkelleyrtp Mar 6, 2024
73e7c3e
Attempt order invariance
jkelleyrtp Mar 6, 2024
fa04edf
use hashmap defaulthasher
jkelleyrtp Mar 6, 2024
95d7012
fix hashing system, bump wasm-bindgen
jkelleyrtp Mar 6, 2024
713ab98
fix els bug
jkelleyrtp Mar 6, 2024
f7f416e
Fix hydration
jkelleyrtp Mar 6, 2024
81f38a0
cfg out globalhotkey
jkelleyrtp Mar 7, 2024
08d054f
Merge branch 'main' into jk/fix-form-inputs
jkelleyrtp Mar 7, 2024
1f6195b
try new hashing strategy
jkelleyrtp Mar 7, 2024
60616d0
fix liveview
jkelleyrtp Mar 7, 2024
e02e41d
Attempt even dumber hashing mechanism
jkelleyrtp Mar 7, 2024
8df87c6
debug windows build
jkelleyrtp Mar 7, 2024
99748a6
move debug
jkelleyrtp Mar 7, 2024
f65ded2
raw bytes instead of str
jkelleyrtp Mar 7, 2024
f073322
use md5 instead
jkelleyrtp Mar 7, 2024
c75aa48
add warning
jkelleyrtp Mar 7, 2024
a2907d1
dont even hash it!
jkelleyrtp Mar 7, 2024
c99c07d
warn
jkelleyrtp Mar 7, 2024
2995647
trim line feeds
jkelleyrtp Mar 7, 2024
bb5ecd7
clean up some examples, ensuring stuff works
jkelleyrtp Mar 7, 2024
c3df8c5
fix windows, enable tokio for examples on wasm
jkelleyrtp Mar 7, 2024
feb80ce
remove old interpreter
jkelleyrtp Mar 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Switch to bun, clean up web implementation
jkelleyrtp committed Mar 4, 2024
commit 22266cc5608a6b34d3db5e49904fba70cb816fd3
2 changes: 2 additions & 0 deletions packages/desktop/headless_tests/utils.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(unused)] // for whatever reason, the compiler is not recognizing the use of these functions

use dioxus::prelude::*;
use dioxus_core::Element;

2 changes: 1 addition & 1 deletion packages/desktop/js/prevent_file_upload.js
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
let target_id = find_real_id(target);
if (target_id !== null) {
const send = (event_name) => {
const message = window.interpreter.serializeIpcMessage("file_diolog", { accept: target.getAttribute("accept"), directory: target.getAttribute("webkitdirectory") === "true", multiple: target.hasAttribute("multiple"), target: parseInt(target_id), bubbles: event_bubbles(event_name), event: event_name });
const message = window.interpreter.serializeIpcMessage("file_dialog", { accept: target.getAttribute("accept"), directory: target.getAttribute("webkitdirectory") === "true", multiple: target.hasAttribute("multiple"), target: parseInt(target_id), bubbles: event_bubbles(event_name), event: event_name });
window.ipc.postMessage(message);
};
send("change&input");
2 changes: 1 addition & 1 deletion packages/desktop/src/ipc.rs
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ impl IpcMessage {
pub(crate) fn method(&self) -> IpcMethod {
match self.method.as_str() {
// todo: this is a misspelling, needs to be fixed
"file_diolog" => IpcMethod::FileDialog,
"file_dialog" => IpcMethod::FileDialog,
"user_event" => IpcMethod::UserEvent,
"query" => IpcMethod::Query,
"browser_open" => IpcMethod::BrowserOpen,
2 changes: 1 addition & 1 deletion packages/desktop/src/protocol.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{assets::*, edits::EditQueue};
use dioxus_interpreter_js::unified_bindings::{native_js, SLEDGEHAMMER_JS};
use dioxus_interpreter_js::unified_bindings::native_js;
use std::path::{Path, PathBuf};
use wry::{
http::{status::StatusCode, Request, Response},
2 changes: 1 addition & 1 deletion packages/interpreter/src/js/hash.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4429706825984325407
3599957386864841107
5 changes: 4 additions & 1 deletion packages/interpreter/src/js/native.js
Original file line number Diff line number Diff line change
@@ -11,13 +11,16 @@ class Interpreter {
this.handler = handler;
this.initialize(root);
}
initialize(root) {
initialize(root, handler = null) {
this.global = {};
this.local = {};
this.root = root;
this.nodes = [root];
this.stack = [root];
this.templates = {};
if (handler) {
this.handler = handler;
}
}
createListener(event_name, element, bubbles) {
if (bubbles) {
86 changes: 85 additions & 1 deletion packages/interpreter/src/js/web.js
Original file line number Diff line number Diff line change
@@ -11,13 +11,16 @@ class Interpreter {
this.handler = handler;
this.initialize(root);
}
initialize(root) {
initialize(root, handler = null) {
this.global = {};
this.local = {};
this.root = root;
this.nodes = [root];
this.stack = [root];
this.templates = {};
if (handler) {
this.handler = handler;
}
}
createListener(event_name, element, bubbles) {
if (bubbles) {
@@ -73,6 +76,86 @@ class Interpreter {
}
}

// src/ts/set_attribute.ts
function setAttributeInner(node, field, value, ns) {
if (ns === "style") {
node.style.setProperty(field, value);
return;
}
if (!!ns) {
node.setAttributeNS(ns, field, value);
return;
}
switch (field) {
case "value":
if (node.value !== value) {
node.value = value;
}
break;
case "initial_value":
node.defaultValue = value;
break;
case "checked":
node.checked = truthy(value);
break;
case "initial_checked":
node.defaultChecked = truthy(value);
break;
case "selected":
node.selected = truthy(value);
break;
case "initial_selected":
node.defaultSelected = truthy(value);
break;
case "dangerous_inner_html":
node.innerHTML = value;
break;
default:
if (!truthy(value) && isBoolAttr(field)) {
node.removeAttribute(field);
} else {
node.setAttribute(field, value);
}
}
}
var truthy = function(val) {
return val === "true" || val === true;
};
var isBoolAttr = function(field) {
switch (field) {
case "allowfullscreen":
case "allowpaymentrequest":
case "async":
case "autofocus":
case "autoplay":
case "checked":
case "controls":
case "default":
case "defer":
case "disabled":
case "formnovalidate":
case "hidden":
case "ismap":
case "itemscope":
case "loop":
case "multiple":
case "muted":
case "nomodule":
case "novalidate":
case "open":
case "playsinline":
case "readonly":
case "required":
case "reversed":
case "selected":
case "truespeed":
case "webkitdirectory":
return true;
default:
return false;
}
};

// src/ts/interpreter_web.ts
class PlatformInterpreter extends Interpreter {
m;
@@ -126,5 +209,6 @@ class PlatformInterpreter extends Interpreter {
}
}
export {
setAttributeInner,
PlatformInterpreter
};
12 changes: 6 additions & 6 deletions packages/interpreter/src/lib.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,12 @@ mod write_native_mutations;
#[cfg(all(feature = "binary-protocol", feature = "sledgehammer"))]
pub use write_native_mutations::*;

#[cfg(feature = "sledgehammer")]
pub mod unified_bindings;

#[cfg(feature = "sledgehammer")]
pub use unified_bindings::*;

// Common bindings for minimal usage.
#[cfg(all(feature = "minimal_bindings", feature = "webonly"))]
pub mod minimal_bindings {
@@ -28,9 +34,3 @@ pub mod minimal_bindings {
pub fn collectFormValues(node: JsValue) -> JsValue;
}
}

#[cfg(feature = "sledgehammer")]
pub mod unified_bindings;

#[cfg(feature = "sledgehammer")]
pub use unified_bindings::*;
6 changes: 5 additions & 1 deletion packages/interpreter/src/ts/interpreter_core.ts
Original file line number Diff line number Diff line change
@@ -28,14 +28,18 @@ export class Interpreter {
this.initialize(root);
}

initialize(root: HTMLElement) {
initialize(root: HTMLElement, handler: EventListener | null = null) {
this.global = {};
this.local = {};
this.root = root;

this.nodes = [root];
this.stack = [root];
this.templates = {};

if (handler) {
this.handler = handler;
}
}

createListener(event_name: string, element: HTMLElement, bubbles: boolean) {
1 change: 1 addition & 0 deletions packages/interpreter/src/ts/interpreter_web.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
// We're using sledgehammer directly

import { Interpreter } from "./interpreter_core";
export { setAttributeInner } from "./set_attribute";

export class PlatformInterpreter extends Interpreter {
m: any;
60 changes: 32 additions & 28 deletions packages/interpreter/src/unified_bindings.rs
Original file line number Diff line number Diff line change
@@ -6,40 +6,13 @@ use wasm_bindgen::prelude::wasm_bindgen;

use sledgehammer_bindgen::bindgen;

/// Combine the interpreter class with the sledgehammer_bindgen generated methods.
pub fn native_js() -> String {
format!("{}\n{}", include_str!("./js/native.js"), GENERATED_JS,)
}

pub const SLEDGEHAMMER_JS: &str = GENERATED_JS;

/// Extensions to the interpreter that are specific to the web platform.
#[cfg(feature = "webonly")]
#[wasm_bindgen(module = "src/js/web.js")]
extern "C" {
pub type WebInterpreter;

#[wasm_bindgen(method, js_name = "saveTemplate")]
pub fn save_template(this: &WebInterpreter, nodes: Vec<Node>, tmpl_id: u16);

#[wasm_bindgen(method)]
pub fn hydrate(this: &WebInterpreter, ids: Vec<u32>);

#[wasm_bindgen(method, js_name = "getNode")]
pub fn get_node(this: &WebInterpreter, id: u32) -> Node;
}

#[cfg(feature = "webonly")]
type PlatformInterpreter = WebInterpreter;

#[cfg(feature = "webonly")]
impl Interpreter {
/// Convert the interpreter to a web interpreter, enabling methods like hydrate and save_template.
pub fn as_web(&self) -> &WebInterpreter {
use wasm_bindgen::prelude::JsCast;
&self.js_channel().unchecked_ref()
}
}

#[bindgen(module)]
mod js {
/// The interpreter extends the core interpreter which contains the state for the interpreter along with some functions that all platforms use like `AppendChildren`.
@@ -222,3 +195,34 @@ mod js {
"{this.els = this.stack.splice(this.stack.length - $n$); let node = this.LoadChild($array$); node.replaceWith(...this.els);}"
}
}

/// Extensions to the interpreter that are specific to the web platform.
#[cfg(feature = "webonly")]
#[wasm_bindgen(module = "src/js/web.js")]
extern "C" {
pub type WebInterpreter;

#[wasm_bindgen(method)]
pub fn initialize(this: &WebInterpreter, root: Node, handler: &js_sys::Function);

#[wasm_bindgen(method, js_name = "saveTemplate")]
pub fn save_template(this: &WebInterpreter, nodes: Vec<Node>, tmpl_id: u16);

#[wasm_bindgen(method)]
pub fn hydrate(this: &WebInterpreter, ids: Vec<u32>);

#[wasm_bindgen(method, js_name = "getNode")]
pub fn get_node(this: &WebInterpreter, id: u32) -> Node;
}

#[cfg(feature = "webonly")]
type PlatformInterpreter = WebInterpreter;

#[cfg(feature = "webonly")]
impl Interpreter {
/// Convert the interpreter to a web interpreter, enabling methods like hydrate and save_template.
pub fn as_web(&self) -> &WebInterpreter {
use wasm_bindgen::prelude::JsCast;
&self.js_channel().unchecked_ref()
}
}
10 changes: 0 additions & 10 deletions packages/interpreter/tsconfig.native.json

This file was deleted.

10 changes: 0 additions & 10 deletions packages/interpreter/tsconfig.web.json

This file was deleted.

2 changes: 1 addition & 1 deletion packages/liveview/src/lib.rs
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ pub enum LiveViewError {
}

fn handle_edits_code() -> String {
use dioxus_interpreter_js::binary_protocol::SLEDGEHAMMER_JS;
use dioxus_interpreter_js::unified_bindings::SLEDGEHAMMER_JS;
use minify_js::{minify, Session, TopLevelMode};

let serialize_file_uploads = r#"if (
5 changes: 2 additions & 3 deletions packages/plasmo/src/hooks.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@ use dioxus_html::input_data::keyboard_types::{Code, Key, Location, Modifiers};
use dioxus_html::input_data::{
MouseButton as DioxusMouseButton, MouseButtonSet as DioxusMouseButtons,
};
use dioxus_html::FormValue;
use dioxus_html::{event_bubbles, prelude::*};
use std::any::Any;
use std::collections::HashMap;
@@ -67,7 +66,7 @@ impl EventData {
pub struct FormData {
pub(crate) value: String,

pub values: HashMap<String, FormValue>,
pub values: HashMap<String, String>,

pub(crate) files: Option<Files>,
}
@@ -77,7 +76,7 @@ impl HasFormData for FormData {
self.value.clone()
}

fn values(&self) -> HashMap<String, FormValue> {
fn values(&self) -> HashMap<String, String> {
self.values.clone()
}

3 changes: 3 additions & 0 deletions packages/web/ric_raf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
requestIdleCallback and requestAnimationFrame implemenation

These currently actually slow down our DOM patching and thus are temporarily removed. Technically we can schedule around rIC and rAF but choose not to.
File renamed without changes.
File renamed without changes.
Loading