const [operation, data, option] = await dioxus.recv();
try {
if (operation === "copy") {
if (!navigator.clipboard?.writeText) return "unsupported";
await navigator.clipboard.writeText(data);
return "ok";
}
const node = document.getElementById(data);
if (!node) return "missing";
if (operation === "edges" || operation === "page") {
if (operation === "page") {
const rtl = getComputedStyle(node).direction === "rtl";
node.scrollBy({ left: (option === "next" ? 1 : -1) * node.clientWidth * 0.85 * (rtl ? -1 : 1) });
return "ok";
}
const offset = Math.abs(node.scrollLeft);
const max = node.scrollWidth - node.clientWidth;
return `${offset <= 1} ${offset >= max - 1}`;
}
if (operation === "place") {
const invoker = document.getElementById(option);
if (!invoker) return "missing";
const anchor = invoker.getBoundingClientRect();
const below = window.innerHeight - anchor.bottom;
const above = anchor.top;
const GAP = 2;
const flip = below < 160 && above > below;
const style = node.style;
style.setProperty("inset-block-start", flip ? "auto" : `${anchor.bottom + GAP}px`);
style.setProperty("inset-block-end", flip ? `${window.innerHeight - above + GAP}px` : "auto");
style.setProperty("inset-inline-start", `${anchor.left}px`);
style.setProperty("min-inline-size", `${anchor.width}px`);
const available = (flip ? above : below) - GAP;
style.setProperty("max-block-size", `${Math.max(80, Math.min(available, 384))}px`);
return "ok";
}
if (operation === "point") {
const [x, y, flipY, edge] = option.split(",");
const style = node.style;
style.position = "fixed";
style.insetBlockStart = `${Number(y)}px`;
style.insetInlineEnd = "auto";
style.insetBlockEnd = "auto";
style.margin = "0";
const rtl = getComputedStyle(node).direction === "rtl";
const rect = node.getBoundingClientRect();
const viewWidth = document.documentElement.clientWidth;
const viewHeight = document.documentElement.clientHeight;
const side = edge || (rtl ? "right" : "left");
const wanted = side === "left" ? Number(x) : Number(x) - rect.width;
const left = Math.min(Math.max(0, wanted), Math.max(0, viewWidth - rect.width));
style.insetInlineStart = `${rtl ? viewWidth - left - rect.width : left}px`;
if (Number(y) + rect.height > viewHeight) {
const above = (flipY === "" ? Number(y) : Number(flipY)) - rect.height;
style.insetBlockStart = `${above >= 0 ? above : Math.max(0, viewHeight - rect.height)}px`;
}
return "ok";
}
if (operation === "below") {
const rect = node.getBoundingClientRect();
const rtl = getComputedStyle(node).direction === "rtl";
return `${rtl ? rect.right : rect.left},${rect.bottom + 4},${rect.top - 4},${rtl ? "right" : "left"}`;
}
if (operation === "capture") {
try { node.setPointerCapture(Number(option)); return "ok"; } catch { return "rejected"; }
}
if (operation === "indeterminate") {
if (!("indeterminate" in node)) return "unsupported";
node.indeterminate = option === "on";
return "ok";
}
if (operation === "reload") {
if (!(node instanceof HTMLIFrameElement)) return "unsupported";
node.src = node.src;
return "ok";
}
const method = {
modal: "showModal", close: "close", focus: "focus", scroll: "scrollIntoView",
popover: option === "open" ? "showPopover" : "hidePopover",
}[operation];
if (!method || typeof node[method] !== "function") return "unsupported";
if (operation === "scroll") node[method]({ block: option, behavior: "instant" });
else node[method]();
return "ok";
} catch {
return "rejected";
}