// 说明:该插件用于把 ONLYOFFICE 编辑器“选区读/写”能力暴露给宿主页面(MNOTE)。 // 宿主页面通过 postMessage 下发 oo_* 工具调用;插件执行后再 postMessage 回传结果。 (function () { const CHANNEL = "mnote_onlyoffice_agent_tools_v1"; const safePostToTop = (payload) => { try { if (typeof window === "undefined") return; if (!window.top) return; window.top.postMessage({ channel: CHANNEL, ...payload }, "*"); } catch { // ignore } }; const execMethod = (method, args) => new Promise((resolve, reject) => { try { if (!window.Asc || !window.Asc.plugin) throw new Error("ONLYOFFICE 插件 API 未就绪"); window.Asc.plugin.executeMethod(method, Array.isArray(args) ? args : [], (res) => resolve(res)); } catch (e) { reject(e instanceof Error ? e : new Error(String(e))); } }); const handleTool = async (tool, args) => { const a = args && typeof args === "object" ? args : {}; if (tool === "oo_get_selection") { // 说明:先做最基础的“纯文本选区读取”,HTML 可在后续升级(需要更复杂的导出方式)。 const text = await execMethod("GetSelectedText", []); return { format: "text", text: String(text ?? "") }; } if (tool === "oo_replace_selection") { const format = String(a.format ?? "text"); const text = String(a.text ?? ""); if (format === "html") { await execMethod("PasteHtml", [text]); return { ok: true, format: "html", length: text.length }; } await execMethod("PasteText", [text]); return { ok: true, format: "text", length: text.length }; } if (tool === "oo_insert_text") { const text = String(a.text ?? ""); await execMethod("PasteText", [text]); return { ok: true, length: text.length }; } if (tool === "oo_insert_html") { const html = String(a.html ?? ""); await execMethod("PasteHtml", [html]); return { ok: true, length: html.length }; } if (tool === "oo_insert_image") { // 说明:优先用 HTML 插入 ,避免依赖 PutImageDataToSelection 的参数差异。 const src = String(a.src ?? a.imageData ?? ""); if (!src) throw new Error("缺少图片数据(src/imageData)"); const w = Number(a.width ?? 0); const h = Number(a.height ?? 0); const widthAttr = Number.isFinite(w) && w > 0 ? ` width=\"${Math.floor(w)}\"` : ""; const heightAttr = Number.isFinite(h) && h > 0 ? ` height=\"${Math.floor(h)}\"` : ""; const html = ``; await execMethod("PasteHtml", [html]); return { ok: true }; } throw new Error(`未知工具:${tool}`); }; window.Asc = window.Asc || {}; window.Asc.plugin = window.Asc.plugin || {}; window.Asc.plugin.init = function () { safePostToTop({ type: "ready" }); }; window.addEventListener("message", async (ev) => { const msg = ev && ev.data ? ev.data : null; if (!msg || typeof msg !== "object") return; if (msg.channel !== CHANNEL) return; if (msg.type !== "call") return; const callId = String(msg.callId ?? "").trim(); const tool = String(msg.tool ?? "").trim(); const args = msg.args && typeof msg.args === "object" ? msg.args : {}; if (!callId || !tool) return; try { const result = await handleTool(tool, args); safePostToTop({ type: "result", callId, ok: true, result }); } catch (e) { const err = e instanceof Error ? e.message : String(e); safePostToTop({ type: "result", callId, ok: false, error: err }); } }); })();