Files
plainleaf/client/document_editor_js.ts
T
MrMugameandGitHub eb6b232444 Fix document editors on safari (#1710)
* Revert document editors to old model

Safari had issues with the previous "hacky" way

* Cleaup panel code
2025-11-28 14:40:05 +01:00

82 lines
2.2 KiB
TypeScript

export default `
const pendingRequests = new Map();
let requestID = 0;
globalThis.silverbullet = new EventTarget();
globalThis.silverbullet.syscall = (name, ...args) => {
const promise = Promise.withResolvers();
pendingRequests.set(++requestID, { ...promise });
globalThis.parent.postMessage({
type: "syscall",
data: {
id: requestID,
name,
args,
},
}, "*");
return promise.promise;
};
globalThis.addEventListener("message", (message) => {
const response = message.data, data = message.data.data;
// Passthrough non internal events
if (!response.internal) {
globalThis.silverbullet.dispatchEvent(new CustomEvent(response.type, { detail: data }));
return;
}
switch (response.type) {
case "syscall-response": {
const id = data.id;
const request = pendingRequests.get(id);
if (!request) {
console.error(\`Failed to lookup request with id \${id}\`);
throw Error("Invalid request id");
}
pendingRequests.delete(id);
if (data.error) {
request.reject(new Error(data.error));
} else {
request.resolve(data.result);
}
} break;
case "set-theme": {
document.querySelector("html").setAttribute("data-theme", data.theme);
} break;
}
});
globalThis.silverbullet.sendMessage = (type, data) => {
globalThis.parent.postMessage({ type, data }, "*");
};
// When an iframe is focused, all keyboard events will be captured by the
// iframe. This is bad because we obviously want stuff like the command
// picker to keep working. This is done by listening to the event **in the
// capture phase** (so we get it first), sending it to the actual SB DOM,
// and only if it doesn't have defaultPrevented set, we send it further
// down.
globalThis.addEventListener("keydown", (event) => {
// This is really hacky... open to other solutions
const keyEvent = new KeyboardEvent("keydown", event);
Object.defineProperty(keyEvent, "target", {
value: globalThis.parent.document.body,
});
globalThis.parent.document.dispatchEvent(keyEvent);
if (keyEvent.defaultPrevented) {
event.preventDefault();
event.stopPropagation();
}
}, true);
`;