wip: native file handles when dropping 🎉

This commit is contained in:
Jonathan Kelley committed 2024-03-05 13:57:28 -08:00
1 parent 403e8e2f49
commit 78d16536a7
11 files changed
+134 -76

No files matched your search

+1 -1
View File
@@ -1 +1 @@
12023679989252671232
2617078454438840343
+18 -17
View File
@@ -248,6 +248,8 @@ class NativeInterpreter extends JSChannel_ {
initialize(root) {
this.intercept_link_redirects = true;
this.liveview = false;
const dragEventHandler = (e) => {
};
window.addEventListener("dragover", function(e) {
if (e.target instanceof Element && e.target.tagName != "INPUT") {
e.preventDefault();
@@ -349,25 +351,8 @@ class NativeInterpreter extends JSChannel_ {
} else {
const message = this.serializeIpcMessage("user_event", body);
this.ipc.postMessage(message);
console.log("sent message to host: ", message);
}
}
async readFiles(target, contents, bubbles, realId, name) {
let files = target.files;
let file_contents = {};
for (let i = 0;i < files.length; i++) {
const file = files[i];
file_contents[file.name] = Array.from(new Uint8Array(await file.arrayBuffer()));
}
contents.files = { files: file_contents };
const message = this.serializeIpcMessage("user_event", {
name,
element: realId,
data: contents,
bubbles
});
this.ipc.postMessage(message);
}
preventDefaults(event, target) {
let preventDefaultRequests = null;
if (target instanceof Element) {
@@ -415,6 +400,22 @@ class NativeInterpreter extends JSChannel_ {
this.waitForRequest(headless);
});
}
async readFiles(target, contents, bubbles, realId, name) {
let files = target.files;
let file_contents = {};
for (let i = 0;i < files.length; i++) {
const file = files[i];
file_contents[file.name] = Array.from(new Uint8Array(await file.arrayBuffer()));
}
contents.files = { files: file_contents };
const message = this.serializeIpcMessage("user_event", {
name,
element: realId,
data: contents,
bubbles
});
this.ipc.postMessage(message);
}
}
export {
NativeInterpreter
+68 -34
View File
@@ -29,10 +29,50 @@ export class NativeInterpreter extends JSChannel_ {
}
initialize(root: HTMLElement): void {
this.intercept_link_redirects = true;
this.liveview = false;
const dragEventHandler = (e: DragEvent) => {
// e.preventDefault();
// e.dataTransfer.effectAllowed = 'none';
// e.dataTransfer.dropEffect = 'none';
//
// we need to signal to the host to provide a native file path,
// not the one coming from here
// We can't get native
// if (e.type === "drop") {
// let target = e.target;
// if (target instanceof Element) {
// let target_id = getTargetId(target);
// if (target_id !== null) {
// const message = this.serializeIpcMessage("file_drop", {
// event: "drop",
// target: target_id,
// data: Array.from(e.dataTransfer.files).map(file => {
// return {
// name: file.name,
// type: file.type,
// size: file.size,
// };
// }),
// });
// this.ipc.postMessage(message);
// }
// }
// }
};
// ["dragenter", "dragover", "drop"].forEach((event) => {
// window.addEventListener(event, dragEventHandler, false)
// });
// attach an event listener on the body that prevents file drops from navigating
// this is because the browser will try to navigate to the file if it's dropped on the window
window.addEventListener("dragover", function (e) {
@@ -51,9 +91,6 @@ export class NativeInterpreter extends JSChannel_ {
// Dropping a file on the window will navigate to the file, which we don't want
e.preventDefault();
// if the element has a drop listener on it, we should send a message to the host with the contents of the drop instead
}, false);
// attach a listener to the route that listens for clicks and prevents the default file dialog
@@ -123,7 +160,7 @@ export class NativeInterpreter extends JSChannel_ {
}
}
// ignore the fact the base interpreter uses ptr + len but we use array
// ignore the fact the base interpreter uses ptr + len but we use array...
// @ts-ignore
loadChild(array: number[]) {
// iterate through each number and get that child
@@ -168,9 +205,6 @@ export class NativeInterpreter extends JSChannel_ {
// Liveview will still need to use this
this.preventDefaults(event, target);
// liveview does not have syncronous event handling, so we need to send the event to the host
if (this.liveview) {
// Okay, so the user might've requested some files to be read
@@ -184,8 +218,6 @@ export class NativeInterpreter extends JSChannel_ {
const message = this.serializeIpcMessage("user_event", body);
this.ipc.postMessage(message);
console.log("sent message to host: ", message);
// // Run the event handler on the virtualdom
// // capture/prevent default of the event if the virtualdom wants to
// const res = handleVirtualdomEventSync(JSON.stringify(body));
@@ -200,30 +232,6 @@ export class NativeInterpreter extends JSChannel_ {
}
}
// A liveview only function
// Desktop will intercept the event before it hits this
async readFiles(target: HTMLInputElement, contents: SerializedEvent, bubbles: boolean, realId: NodeId, name: string) {
let files = target.files!;
let file_contents: { [name: string]: number[] } = {};
for (let i = 0; i < files.length; i++) {
const file = files[i];
file_contents[file.name] = Array.from(
new Uint8Array(await file.arrayBuffer())
);
}
contents.files = { files: file_contents };
const message = this.serializeIpcMessage("user_event", {
name: name,
element: realId,
data: contents,
bubbles,
});
this.ipc.postMessage(message);
}
// This should:
@@ -308,6 +316,32 @@ export class NativeInterpreter extends JSChannel_ {
this.waitForRequest(headless);
});
}
// A liveview only function
// Desktop will intercept the event before it hits this
async readFiles(target: HTMLInputElement, contents: SerializedEvent, bubbles: boolean, realId: NodeId, name: string) {
let files = target.files!;
let file_contents: { [name: string]: number[] } = {};
for (let i = 0; i < files.length; i++) {
const file = files[i];
file_contents[file.name] = Array.from(
new Uint8Array(await file.arrayBuffer())
);
}
contents.files = { files: file_contents };
const message = this.serializeIpcMessage("user_event", {
name: name,
element: realId,
data: contents,
bubbles,
});
this.ipc.postMessage(message);
}
}
type EventSyncResult = {