1
0
silverbullet/plugs/markdown/assets/markdown_widget.js
2023-10-29 10:14:18 +01:00

108 lines
3.5 KiB
JavaScript

async function init() {
// Make edit button send the "blur" API call so that the MD code is visible
document.getElementById("edit-button").addEventListener("click", () => {
api({ type: "blur" });
});
document.getElementById("reload-button").addEventListener("click", () => {
api({ type: "reload" });
});
document.getElementById("source-button").addEventListener("click", () => {
document.getElementById("body-content").innerText = originalMarkdown;
});
document.querySelectorAll("a[data-ref]").forEach((el) => {
el.addEventListener("click", (e) => {
e.preventDefault();
syscall("editor.navigate", el.dataset.ref);
});
});
// Find all fenced code blocks and replace them with iframes (if a code widget is defined for them)
const allWidgets = document.querySelectorAll("pre[data-lang]");
for (const widget of allWidgets) {
const lang = widget.getAttribute("data-lang");
const body = widget.innerText;
try {
const result = await syscall("widget.render", lang, body);
const iframe = document.createElement("iframe");
iframe.src = "about:blank";
iframe.onload = () => {
iframe.contentDocument.write(panelHtml);
iframe.contentWindow.postMessage({
type: "html",
theme: document.getElementsByTagName("html")[0].getAttribute(
"data-theme",
),
...result,
}, "*");
};
widget.parentNode.replaceChild(iframe, widget);
globalThis.addEventListener("message", (e) => {
if (e.source !== iframe.contentWindow) {
return;
}
const messageData = e.data;
switch (messageData.type) {
case "setHeight":
iframe.style.height = messageData.height + "px";
// Propagate height setting to parent
updateHeight();
break;
case "syscall": {
// Intercept syscall messages and send them to the parent
const { id, name, args } = messageData;
syscall(name, ...args).then((result) => {
iframe.contentWindow.postMessage(
{ id, type: "syscall-response", result },
"*",
);
}).catch((error) => {
iframe.contentWindow.postMessage({
id,
type: "syscall-response",
error,
}, "*");
});
break;
}
default:
// Bubble up any other messages to parent iframe
window.parent.postMessage(messageData, "*");
}
});
} catch (e) {
if (e.message.includes("not found")) {
// Not a code widget, ignore
} else {
console.error("Error rendering widget", e);
}
}
}
// Find all task toggles and propagate their state
document.querySelectorAll("span[data-external-task-ref]").forEach((el) => {
const taskRef = el.dataset.externalTaskRef;
el.querySelector("input[type=checkbox]").addEventListener("change", (e) => {
const oldState = e.target.dataset.state;
const newState = oldState === " " ? "x" : " ";
// Update state in DOM as well for future toggles
e.target.dataset.state = newState;
console.log("Toggling task", taskRef);
syscall(
"system.invokeFunction",
"tasks.updateTaskState",
taskRef,
oldState,
newState,
).catch(
console.error,
);
});
});
}
init().catch(console.error);