Files
dioxus/packages/desktop/src/index.js
T

487 lines
11 KiB
JavaScript

class Interpreter {
constructor(root) {
this.root = root;
this.stack = [root];
this.listeners = {
"onclick": {}
};
this.lastNodeWasText = false;
this.nodes = [root];
}
top() {
return this.stack[this.stack.length - 1];
}
pop() {
return this.stack.pop();
}
PushRoot(edit) {
const id = edit.root;
const node = this.nodes[id];
this.stack.push(node);
}
PopRoot(_edit) {
this.stack.pop();
}
AppendChildren(edit) {
let root = this.stack[this.stack.length - (1 + edit.many)];
let to_add = this.stack.splice(this.stack.length - edit.many);
for (let i = 0; i < edit.many; i++) {
root.appendChild(to_add[i]);
}
}
ReplaceWith(edit) {
// console.log(edit);
let root = this.nodes[edit.root];
let els = this.stack.splice(this.stack.length - edit.m);
// console.log(root);
// console.log(els);
root.replaceWith(...els);
}
InsertAfter(edit) {
let old = this.nodes[edit.root];
let new_nodes = this.stack.splice(this.stack.length - edit.n);
old.after(...new_nodes);
}
InsertBefore(edit) {
let old = this.nodes[edit.root];
let new_nodes = this.stack.splice(this.stack.length - edit.n);
old.before(...new_nodes);
}
Remove(edit) {
let node = this.nodes[edit.root];
if (node !== undefined) {
node.remove();
}
}
CreateTextNode(edit) {
const node = document.createTextNode(edit.text);
this.nodes[edit.root] = node;
this.stack.push(node);
}
CreateElement(edit) {
const tagName = edit.tag;
const el = document.createElement(tagName);
this.nodes[edit.root] = el;
this.stack.push(el);
}
CreateElementNs(edit) {
let el = document.createElementNS(edit.ns, edit.tag);
this.stack.push(el);
this.nodes[edit.root] = el;
}
CreatePlaceholder(edit) {
let el = document.createElement("pre");
this.stack.push(el);
this.nodes[edit.root] = el;
}
RemoveEventListener(edit) { }
NewEventListener(edit) {
const event_name = edit.event_name;
const mounted_node_id = edit.root;
const scope = edit.scope;
const element = this.nodes[edit.root]
element.setAttribute(`dioxus-event-${event_name}`, `${scope}.${mounted_node_id}`);
if (this.listeners[event_name] === undefined) {
this.listeners[event_name] = "bla";
this.root.addEventListener(event_name, (event) => {
// console.log("CLICKED");
const target = event.target;
const val = target.getAttribute(`dioxus-event-${event_name}`);
if (val == null) {
return;
}
const fields = val.split(".");
const scope_id = parseInt(fields[0]);
const real_id = parseInt(fields[1]);
// // console.log(`parsed event with scope_id ${scope_id} and real_id ${real_id}`);
// console.log("message fired");
let contents = serialize_event(event);
let evt = {
event: event_name,
scope: scope_id,
mounted_dom_id: real_id,
contents: contents,
};
// console.log(evt);
rpc.call('user_event', evt).then((reply) => {
// console.log("reply received", reply);
this.stack.push(this.root);
reply.map((reply) => {
let edits = reply.edits;
for (let x = 0; x < edits.length; x++) {
let edit = edits[x];
let f = this[edit.type];
f.call(this, edit);
}
});
})
});
}
}
SetText(edit) {
this.nodes[edit.root].textContent = edit.text;
}
SetAttribute(edit) {
// console.log("setting attr", edit);
const name = edit.field;
const value = edit.value;
const ns = edit.ns;
const node = this.nodes[edit.root]
if (ns == "style") {
node.style[name] = value;
} else if ((ns != null) || (ns != undefined)) {
node.setAttributeNS(ns, name, value);
} else {
switch (name) {
case "value":
node.value = value;
break;
case "checked":
// console.log("setting checked");
node.checked = (value === "true");
break;
case "selected":
node.selected = (value === "true");
break;
case "dangerous_inner_html":
node.innerHTML = value;
break;
default:
// console.log("setting attr directly ", name, value);
node.setAttribute(name, value);
}
}
}
RemoveAttribute(edit) {
const name = edit.field;
const node = this.nodes[edit.root];
node.removeAttribute(name);
if (name === "value") {
node.value = null;
}
if (name === "checked") {
node.checked = false;
}
if (name === "selected") {
node.selected = false;
}
}
}
async function initialize() {
let root = window.document.getElementById("_dioxusroot");
const interpreter = new Interpreter(root);
const reply = await rpc.call('initiate');
let pre_rendered = reply.pre_rendered;
if (pre_rendered !== undefined) {
root.innerHTML = pre_rendered;
}
const edits = reply.edits;
apply_edits(edits, interpreter);
}
function apply_edits(edits, interpreter) {
// console.log(edits);
for (let x = 0; x < edits.length; x++) {
let edit = edits[x];
let f = interpreter[edit.type];
f.call(interpreter, edit);
}
// // console.log("stack completed: ", interpreter.stack);
}
function serialize_event(event) {
let serializer = SerializeMap[event.type];
if (serializer === undefined) {
return {};
} else {
return serializer(event);
}
}
const SerializeMap = {
"copy": serialize_clipboard,
"cut": serialize_clipboard,
"paste": serialize_clipboard,
"compositionend": serialize_composition,
"compositionstart": serialize_composition,
"compositionupdate": serialize_composition,
"keydown": serialize_keyboard,
"keypress": serialize_keyboard,
"keyup": serialize_keyboard,
"focus": serialize_focus,
"blur": serialize_focus,
// "change": serialize_form,
"change": serialize_change,
"input": serialize_form,
"invalid": serialize_form,
"reset": serialize_form,
"submit": serialize_form,
"click": serialize_mouse,
"contextmenu": serialize_mouse,
"doubleclick": serialize_mouse,
"drag": serialize_mouse,
"dragend": serialize_mouse,
"dragenter": serialize_mouse,
"dragexit": serialize_mouse,
"dragleave": serialize_mouse,
"dragover": serialize_mouse,
"dragstart": serialize_mouse,
"drop": serialize_mouse,
"mousedown": serialize_mouse,
"mouseenter": serialize_mouse,
"mouseleave": serialize_mouse,
"mousemove": serialize_mouse,
"mouseout": serialize_mouse,
"mouseover": serialize_mouse,
"mouseup": serialize_mouse,
"pointerdown": serialize_pointer,
"pointermove": serialize_pointer,
"pointerup": serialize_pointer,
"pointercancel": serialize_pointer,
"gotpointercapture": serialize_pointer,
"lostpointercapture": serialize_pointer,
"pointerenter": serialize_pointer,
"pointerleave": serialize_pointer,
"pointerover": serialize_pointer,
"pointerout": serialize_pointer,
"select": serialize_selection,
"touchcancel": serialize_touch,
"touchend": serialize_touch,
"touchmove": serialize_touch,
"touchstart": serialize_touch,
"scroll": serialize_scroll,
"wheel": serialize_wheel,
"animationstart": serialize_animation,
"animationend": serialize_animation,
"animationiteration": serialize_animation,
"transitionend": serialize_transition,
"abort": serialize_media,
"canplay": serialize_media,
"canplaythrough": serialize_media,
"durationchange": serialize_media,
"emptied": serialize_media,
"encrypted": serialize_media,
"ended": serialize_media,
"error": serialize_media,
"loadeddata": serialize_media,
"loadedmetadata": serialize_media,
"loadstart": serialize_media,
"pause": serialize_media,
"play": serialize_media,
"playing": serialize_media,
"progress": serialize_media,
"ratechange": serialize_media,
"seeked": serialize_media,
"seeking": serialize_media,
"stalled": serialize_media,
"suspend": serialize_media,
"timeupdate": serialize_media,
"volumechange": serialize_media,
"waiting": serialize_media,
"toggle": serialize_toggle
}
function serialize_clipboard(_event) {
return {};
}
function serialize_composition(event) {
return {
data: event.data
}
}
function serialize_keyboard(event) {
return {
char_code: event.charCode,
key: event.key,
alt_key: event.altKey,
ctrl_key: event.ctrlKey,
meta_key: event.metaKey,
key_code: event.keyCode,
shift_key: event.shiftKey,
locale: "locale",
// locale: event.locale,
location: event.location,
repeat: event.repeat,
which: event.which,
}
}
function serialize_focus(_event) {
return {}
}
function serialize_change(event) {
let target = event.target;
let value;
if (target.type === "checkbox" || target.type === "radio") {
value = target.checked ? "true" : "false";
} else {
value = target.value ?? target.textContent;
}
return {
value: value
}
}
function serialize_form(event) {
let target = event.target;
let value = target.value ?? target.textContent;
return {
value: value
}
}
function serialize_mouse(event) {
return {
alt_key: event.altKey,
button: event.button,
buttons: event.buttons,
client_x: event.clientX,
client_y: event.clientY,
ctrl_key: event.ctrlKey,
meta_key: event.metaKey,
page_x: event.pageX,
page_y: event.pageY,
screen_x: event.screenX,
screen_y: event.screenY,
shift_key: event.shiftKey,
}
}
function serialize_pointer(event) {
return {
alt_key: event.altKey,
button: event.button,
buttons: event.buttons,
client_x: event.clientX,
client_y: event.clientY,
ctrl_key: event.ctrlKey,
meta_key: event.metaKey,
page_x: event.pageX,
page_y: event.pageY,
screen_x: event.screenX,
screen_y: event.screenY,
shift_key: event.shiftKey,
pointer_id: event.pointerId,
width: event.width,
height: event.height,
pressure: event.pressure,
tangential_pressure: event.tangentialPressure,
tilt_x: event.tiltX,
tilt_y: event.tiltY,
twist: event.twist,
pointer_type: event.pointerType,
is_primary: event.isPrimary,
}
}
function serialize_selection(event) {
return {}
}
function serialize_touch(event) {
return {
alt_key: event.altKey,
ctrl_key: event.ctrlKey,
meta_key: event.metaKey,
shift_key: event.shiftKey,
// changed_touches: event.changedTouches,
// target_touches: event.targetTouches,
// touches: event.touches,
}
}
function serialize_scroll(event) {
return {}
}
function serialize_wheel(event) {
return {
delta_x: event.deltaX,
delta_y: event.deltaY,
delta_z: event.deltaZ,
delta_mode: event.deltaMode,
}
}
function serialize_animation(event) {
return {
animation_name: event.animationName,
elapsed_time: event.elapsedTime,
pseudo_element: event.pseudoElement,
}
}
function serialize_transition(event) {
return {
property_name: event.propertyName,
elapsed_time: event.elapsedTime,
pseudo_element: event.pseudoElement,
}
}
function serialize_media(event) {
return {}
}
function serialize_toggle(event) {
return {}
}
initialize();