-
Notifications
You must be signed in to change notification settings - Fork 84
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
percy-dom + virtual-node example wanted #208
Comments
I've created another much smaller test-case so i can re-run the update manually and it seems that percy-dom handles dom-rewrites different from what I was using https://www.npmjs.com/package/diff-dom/v/1.0.0 diff-dom code implementationnoticed difference between implementationsBoth implementations update the DOM-tree in a way that the outcome is 'correct', which is already great! The subtle difference is text selection (didn't see scroll-buffers flipping):
as a consequence: if i have text selected, text inside the to-be-patched node which is not directly updated, it will loose the text selection anyways. To make it abundantly clear: I rewrite this: <div id="ws-id">
<div>Hello World</div>
<div>this is fine, yeah, srly!</div>
</div> Into this: <div id="ws-id">
<div>Hello World</div>
<div>this is fine, yeah, srly!!!</div>
</div> So I never changed the questionIs my conclusion about percy-dom correct, that it removes all the nodes and recreates them instead of updating them? percy/crates/percy-dom/src/pdom.rs Line 27 in b3a3eec
/// Create a new `PercyDom`.
///
/// A root `Node` will be created and it will replace your passed in mount
/// element.
pub fn new_replace_mount(current_vdom: VirtualNode, mount: Element) -> PercyDom {
let pdom = Self::new(current_vdom);
mount
.replace_with_with_node_1(&pdom.root_node)
.expect("Could not replace mount element");
pdom
} The comments confuse me a lot because I don't understand the difference between what is the real DOM and what is the virtual DOM. percy-dom implementationextern crate web_sys;
use log::info;
use percy_dom::event::VirtualEvents;
use percy_dom::patch;
use percy_dom::prelude::*;
use std::cell::Cell;
use std::rc::Rc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue;
use web_sys::Element;
use web_sys::{js_sys, MessageEvent, WebSocket};
#[wasm_bindgen]
pub fn foo() {
static INIT: std::sync::Once = std::sync::Once::new();
static mut PERCY_DOM_ROOT_NODE: Option<PercyDom> = None;
INIT.call_once(|| {
info!("WASM hello world foo");
// Initialize a div with id `ws-div` in the DOM
let initial_div: VirtualNode = html! {<div id="ws-div"></div>};
// Mount the initial VirtualNode to the actual DOM
let root_node: Element = web_sys::window()
.unwrap()
.document()
.unwrap()
.get_element_by_id("ws-div")
.expect("`app` div not found in the DOM");
let percy_dom_root_node = PercyDom::new_replace_mount(initial_div, root_node);
unsafe {
PERCY_DOM_ROOT_NODE = Some(percy_dom_root_node);
}
});
unsafe {
if let Some(percy_dom_root_node) = &mut PERCY_DOM_ROOT_NODE {
info!("updating");
// Code that uses percy_dom_root_node
let input: String = "<div>Hello World</div><div>this is fine!</div>".to_string();
let mut updated_div: VirtualNode = html! {<div id="ws-div"></div>};
updated_div
.as_velement_mut()
.unwrap()
.special_attributes
.dangerous_inner_html = Some(input);
percy_dom_root_node.update(updated_div);
let input2 = "<div>Hello World</div><div>this is fine, yeah, srly!!!</div>".to_string();
let mut updated_div2: VirtualNode = html! {<div id="ws-div"></div>};
updated_div2
.as_velement_mut()
.unwrap()
.special_attributes
.dangerous_inner_html = Some(input2);
percy_dom_root_node.update(updated_div2);
}
}
}
} and with this code: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World</title>
<link rel="icon" href="favicon.ico" type="image/x-icon">
</head>
<script type="module">
import init, { foo } from './pkg/frontend.js';
async function run() {
await init(); // Initialize the WASM module
console.log("Hello World from module init context!");
window.foo = foo; // Make `foo` accessible from the console
//foo(); // Call the `foo` function
}
run();
</script>
<body>
<h1>Hello, World!</h1>
<div><i>Some header text</i></div>
<button onclick="foo()">asdf</button>
<div id="ws-div"><div>xxx</div></div>
<div><b>Some footer text</b></div>
</body>
</html> |
I want to use percy-dom to patch a webpage via patches over a websocket.
This is the position in the webpage I want to modify:
<div id="here">...</div>
There is already some html and this needs to be patched properly.
requirement
So the Rust code should basically:
here
VirtualNode
here
>...Later I want to create the diffs on the server and only stream patches via the websocket.
request for help
Could someone please help me to get a simple example working, ideally we could add this as a tests which are already there:
percy/crates/percy-dom/tests/on_create_element.rs
Line 47 in b3a3eec
I've also studied the patch function signature:
percy/crates/percy-dom/src/patch/apply_patches.rs
Line 22 in b3a3eec
But I don't get the documentation either.
experiment1
here
is not updated yetexperiment2
This code:
experiment3
this combines experiment 1 and experiment 2 but if i select text within the document where no change happened, it will remove the selection. if i select text outside that area it remains selected.
that means that the update removes everything and then adds the new document instead of applying a diff.
The text was updated successfully, but these errors were encountered: