mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-01-10 03:38:56 +00:00
904b26f711
This commit adds a new type - the DomEdit - for serializing the changes made by the diffing machine. The architecture of how DomEdits fit into the cooperative scheduling is still TBD but it will allow us to build change lists without applying them immediately. This is more performant and allows us to only render parts of the page at a time. This commit also adds more infrastructure around webview. Dioxus can now run on the web, generate static pages, run in the desktop, and run on mobile, with a large part of thanks to webview.
131 lines
3.7 KiB
HTML
131 lines
3.7 KiB
HTML
<!-- a js-only interpreter for the dioxus patch stream :) -->
|
|
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
|
|
<meta charset="UTF-8" />
|
|
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet" />
|
|
</head>
|
|
|
|
<body>
|
|
<div></div>
|
|
</body>
|
|
<script>
|
|
class Interpreter {
|
|
constructor(root) {
|
|
this.stack = [root];
|
|
this.lastNodeWasText = false;
|
|
this.nodes = {
|
|
0: root
|
|
};
|
|
}
|
|
|
|
top() {
|
|
return this.stack[this.stack.length - 1];
|
|
}
|
|
|
|
pop() {
|
|
return this.stack.pop();
|
|
}
|
|
}
|
|
|
|
class OPTABLE {
|
|
PushRoot(self, edit) {
|
|
const id = edit.root;
|
|
const node = self.nodes[id];
|
|
self.stack.push(node);
|
|
}
|
|
AppendChild(self, edit) {
|
|
// todo: prevent merging of text nodes
|
|
const node = self.pop();
|
|
self.top().appendChild(node);
|
|
}
|
|
ReplaceWith(self, edit) {
|
|
const newNode = self.pop();
|
|
const oldNode = self.pop();
|
|
oldNode.replaceWith(newNode);
|
|
self.stack.push(newNode);
|
|
}
|
|
Remove(self, edit) {
|
|
const node = self.stack.pop();
|
|
node.remove();
|
|
}
|
|
RemoveAllChildren(self, edit) {
|
|
// todo - we never actually call this one
|
|
}
|
|
CreateTextNode(self, edit) {
|
|
self.stack.push(document.createTextNode(edit.text));
|
|
}
|
|
CreateElement(self, edit) {
|
|
const tagName = edit.tag;
|
|
console.log(`creating element! ${edit}`);
|
|
self.stack.push(document.createElement(tagName));
|
|
}
|
|
CreateElementNs(self, edit) {
|
|
self.stack.push(document.createElementNS(edit.ns, edit.tag));
|
|
}
|
|
CreatePlaceholder(self, edit) {
|
|
self.stack.push(document.createElement("pre"));
|
|
}
|
|
NewEventListener(self, edit) {
|
|
// todo
|
|
}
|
|
RemoveEventListener(self, edit) {
|
|
// todo
|
|
}
|
|
SetText(self, edit) {
|
|
self.top().textContent = edit.text;
|
|
}
|
|
SetAttribute(self, edit) {
|
|
const name = edit.field;
|
|
const value = edit.value;
|
|
const node = self.top(self.stack);
|
|
node.setAttribute(name, value);
|
|
|
|
// Some attributes are "volatile" and don't work through `setAttribute`.
|
|
if ((name === "value", self)) {
|
|
node.value = value;
|
|
}
|
|
if ((name === "checked", self)) {
|
|
node.checked = true;
|
|
}
|
|
if ((name === "selected", self)) {
|
|
node.selected = true;
|
|
}
|
|
}
|
|
RemoveAttribute(self, edit) {
|
|
const name = edit.field;
|
|
const node = self.top(self.stack);
|
|
node.removeAttribute(name);
|
|
|
|
// Some attributes are "volatile" and don't work through `removeAttribute`.
|
|
if ((name === "value", self)) {
|
|
node.value = null;
|
|
}
|
|
if ((name === "checked", self)) {
|
|
node.checked = false;
|
|
}
|
|
if ((name === "selected", self)) {
|
|
node.selected = false;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
const op_table = new OPTABLE();
|
|
const interpreter = new Interpreter(window.document.body);
|
|
|
|
function EditListReceived(rawEditList) {
|
|
let editList = JSON.parse(rawEditList);
|
|
console.warn("hnelllo");
|
|
editList.forEach(function (edit, index) {
|
|
console.log(edit);
|
|
op_table[edit.type](interpreter, edit);
|
|
});
|
|
}
|
|
|
|
external.invoke("initiate");
|
|
</script>
|
|
|
|
</html>
|