import { parsePageRef } from "@silverbulletmd/silverbullet/lib/page_ref"; import type { Client } from "../client.ts"; import { tagPrefix } from "../../plugs/index/constants.ts"; import { extractHashtag } from "@silverbulletmd/silverbullet/lib/tags"; export function attachWidgetEventHandlers( div: HTMLElement, client: Client, pos?: number, ) { div.addEventListener("mousedown", (e) => { if (e.altKey) { // Move cursor there client.editorView.dispatch({ selection: { anchor: pos! } }); client.editorView.focus(); e.preventDefault(); } // CodeMirror overrides mousedown on parent elements to implement its own selection highlighting. // That's nice, but not for markdown widgets, so let's not propagate the event to CodeMirror here. e.stopPropagation(); }); // Override wiki links with local navigate (faster) div.querySelectorAll("a[data-ref]").forEach((el_) => { const el = el_ as HTMLElement; // Override default click behavior with a local navigate (faster) el.addEventListener("click", (e) => { if (e.ctrlKey || e.metaKey) { // Don't do anything special for ctrl/meta clicks return; } e.preventDefault(); e.stopPropagation(); const pageRef = parsePageRef(el.dataset.ref!); client.navigate(pageRef, false, e.ctrlKey || e.metaKey); }); }); // Attach click handlers to hash tags div.querySelectorAll("span.hashtag").forEach((el_) => { const el = el_ as HTMLElement; // Override default click behavior with a local navigate (faster) el.addEventListener("click", (e) => { if (e.ctrlKey || e.metaKey) { // Don't do anything special for ctrl/meta clicks return; } client.navigate({ page: `${tagPrefix}${extractHashtag(el.innerText)}`, pos: 0, }); }); }); div.querySelectorAll("button[data-onclick]").forEach((el_) => { const el = el_ as HTMLElement; const onclick = el.dataset.onclick!; const parsedOnclick = JSON.parse(onclick); if (parsedOnclick[0] === "command") { const command = parsedOnclick[1]; el.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); console.info( "Command link clicked in widget, running", parsedOnclick, ); client.runCommandByName(command, parsedOnclick[2]).catch( console.error, ); }); } }); // Implement task toggling div.querySelectorAll("span[data-external-task-ref]").forEach((el: any) => { const taskRef = el.dataset.externalTaskRef; const input = el.querySelector("input[type=checkbox]")!; input.addEventListener( "click", (e: any) => { // Avoid triggering the click on the parent e.stopPropagation(); }, ); input.addEventListener( "change", (e: any) => { e.stopPropagation(); 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); client.clientSystem.localSyscall( "system.invokeFunction", ["tasks.updateTaskState", taskRef, oldState, newState], ).catch( console.error, ); }, ); }); }