@4399ywkf/editor 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DocView-5KS7B4DA.js → DocView-GDN5CZCJ.js} +3 -3
- package/dist/{DocView-5KS7B4DA.js.map → DocView-GDN5CZCJ.js.map} +1 -1
- package/dist/{chunk-G6WM2PSU.js → chunk-ZRFOS52C.js} +111 -8
- package/dist/chunk-ZRFOS52C.js.map +1 -0
- package/dist/doc-runtime.d.ts +358 -0
- package/dist/doc-runtime.js +774 -0
- package/dist/doc-runtime.js.map +1 -0
- package/dist/doc.js +1 -1
- package/dist/docx.d.ts +121 -6
- package/dist/docx.js +421 -40
- package/dist/docx.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/style.css +22 -0
- package/package.json +15 -11
- package/dist/chunk-G6WM2PSU.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/doc-runtime/litexml.ts","../src/doc-runtime/operations.ts","../src/doc-runtime/runtime.ts"],"names":["type","cell","meta"],"mappings":"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","file":"doc-runtime.js","sourcesContent":["/**\n * LiteXML —— 给 AI 看的文档表示。\n *\n * 设计原则(来自实测与业界先例):\n * 1. 比 ProseMirror JSON 省 token(Notion 换成 markdown、Tiptap 做 Shorthand,\n * 理由都是这个)。实测 7 块中文文档:LiteXML 322 token / PM JSON minified 499\n * (1.55x)/ pretty 898(2.79x)。1.55x 是下限 —— 中文正文占比高时对 JSON 最有利,\n * 嵌套列表和表格会把差距成倍拉大;\n * 2. 每个可寻址块带稳定 id,AI 只用 id 定位,绝不用 position;\n * 3. **有损但不丢失**:表达不了的节点降级成不透明占位符 `<node type=\"...\"/>`,\n * 而不是抛错;表达不了的属性靠写入侧 attrs 合并保住(见 mergeParsedNode)。\n *\n * 本模块是**纯数据变换**:进 ProseMirror JSON 出字符串,或者反过来。\n * 不碰 Editor 实例、不碰 DOM(XML 解析器由调用方注入,同 docx/parse.ts 的做法),\n * 所以可以在 Node 里直接跑往返测试。\n */\nimport type { JSONContent } from \"@tiptap/core\"\n\n/* ------------------------------ 标签表 ------------------------------ */\n\n/**\n * 节点类型 → 标签。不在表里的走 `<node type=\"...\"/>` 兜底。\n *\n * 这张表镜像的是**本编辑器自己的 schema**(30 个节点类型)。它必须和\n * components/tiptap-node/ 下的节点定义住在同一个包里 —— 跨仓之后每加一个节点\n * 类型,序列化就静默降级成占位符,不报错、不丢数据、也不告诉你。\n */\nexport const NODE_TAG: Record<string, string> = {\n paragraph: \"p\",\n bulletList: \"ul\",\n orderedList: \"ol\",\n listItem: \"li\",\n taskList: \"tasks\",\n taskItem: \"task\",\n blockquote: \"quote\",\n codeBlock: \"code\",\n horizontalRule: \"hr\",\n table: \"table\",\n tableRow: \"tr\",\n tableCell: \"td\",\n tableHeader: \"th\",\n image: \"img\",\n video: \"video\",\n audio: \"audio\",\n fileAttachment: \"file\",\n columns: \"cols\",\n column: \"col\",\n tocNode: \"toc\",\n mediaUploadPlaceholder: \"uploading\",\n imageUpload: \"uploading\",\n}\n\nconst TYPE_BY_TAG: Record<string, string> = Object.fromEntries(\n Object.entries(NODE_TAG).map(([type, tag]) => [tag, type]),\n)\n\n/** 叶子节点:自闭合,没有子内容。AI 不应往里写内容。 */\nexport const VOID_TAGS: ReadonlySet<string> = new Set([\n \"hr\",\n \"img\",\n \"video\",\n \"audio\",\n \"file\",\n \"toc\",\n \"uploading\",\n])\n\n/** 只读节点:由扩展自动维护,AI 不许直接写。 */\nexport const READONLY_TAGS: ReadonlySet<string> = new Set([\"toc\", \"uploading\"])\n\n/** 属性名 → XML 上的短名。没列的按原名输出。 */\nconst ATTR_ALIAS: Record<string, string> = {\n textAlign: \"align\",\n nodeTextAlign: \"align\",\n nodeVerticalAlign: \"valign\",\n backgroundColor: \"bg\",\n language: \"lang\",\n}\nconst ATTR_UNALIAS: Record<string, string> = {\n align: \"textAlign\",\n valign: \"nodeVerticalAlign\",\n bg: \"backgroundColor\",\n lang: \"language\",\n}\n\n/** 派生属性:由扩展从别处算出来的,输出给 AI 只是噪音(且写回去会打架)。 */\nconst NOISE_ATTRS: ReadonlySet<string> = new Set([\"data-toc-id\"])\n\n/** 需要还原成非字符串的属性。 */\nconst NUM_ATTRS: ReadonlySet<string> = new Set([\"level\", \"indent\", \"colspan\", \"rowspan\"])\nconst BOOL_ATTRS: ReadonlySet<string> = new Set([\"checked\"])\n\nexport const MARK_TAG: Record<string, string> = {\n bold: \"b\",\n italic: \"i\",\n underline: \"u\",\n strike: \"s\",\n code: \"c\",\n superscript: \"sup\",\n subscript: \"sub\",\n}\nconst MARK_BY_TAG: Record<string, string> = Object.fromEntries(\n Object.entries(MARK_TAG).map(([mark, tag]) => [tag, mark]),\n)\n\n/** 可被 formatText 施加/移除的标记。 */\nexport const FORMATTABLE = Object.keys(MARK_TAG)\n\nexport type FormattableMark =\n | \"bold\"\n | \"italic\"\n | \"underline\"\n | \"strike\"\n | \"code\"\n | \"superscript\"\n | \"subscript\"\n\n/* ------------------------------ 序列化 ------------------------------ */\n\nconst esc = (s: unknown): string =>\n String(s)\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n\nfunction attrsToXml(node: JSONContent): string {\n const out: string[] = []\n const attrs = node.attrs ?? {}\n if (attrs.id) out.push(` id=\"${esc(attrs.id)}\"`)\n for (const [k, v] of Object.entries(attrs)) {\n if (k === \"id\" || v === null || v === undefined || v === \"\" || v === 0 || v === false) continue\n if (NOISE_ATTRS.has(k)) continue\n // colspan/rowspan 默认就是 1,输出出来只是白烧 token\n if ((k === \"colspan\" || k === \"rowspan\") && v === 1) continue\n const name = ATTR_ALIAS[k] ?? k\n if (name === \"id\") continue\n out.push(` ${name}=\"${esc(Array.isArray(v) ? v.join(\",\") : v)}\"`)\n }\n return out.join(\"\")\n}\n\nfunction inlineToXml(nodes: JSONContent[] = []): string {\n return nodes\n .map((n) => {\n if (n.type === \"text\") {\n let out = esc(n.text ?? \"\")\n for (const m of n.marks ?? []) {\n const tag = MARK_TAG[m.type as string]\n if (tag) out = `<${tag}>${out}</${tag}>`\n else if (m.type === \"link\") out = `<a href=\"${esc(m.attrs?.href ?? \"\")}\">${out}</a>`\n else if (m.type === \"highlight\")\n out = `<mark${m.attrs?.color ? ` color=\"${esc(m.attrs.color)}\"` : \"\"}>${out}</mark>`\n else if (m.type === \"textStyle\" && m.attrs?.color)\n out = `<color v=\"${esc(m.attrs.color)}\">${out}</color>`\n }\n return out\n }\n // 内联原子节点:mention / emoji / 公式 / hardBreak\n if (n.type === \"hardBreak\") return \"<br/>\"\n return `<node type=\"${esc(n.type)}\"${attrsToXml(n)}/>`\n })\n .join(\"\")\n}\n\nfunction isBlock(n: JSONContent): boolean {\n return Boolean(n.type && NODE_TAG[n.type]) || n.type === \"heading\"\n}\n\nexport function nodeToXml(node: JSONContent, depth = 0): string {\n const pad = \" \".repeat(depth)\n const attrs = attrsToXml(node)\n\n if (node.type === \"heading\") {\n const lv = node.attrs?.level ?? 1\n const a = attrs.replace(/ level=\"\\d+\"/, \"\")\n return `${pad}<h${lv}${a}>${inlineToXml(node.content)}</h${lv}>`\n }\n\n const tag = node.type ? NODE_TAG[node.type] : undefined\n if (!tag) return `${pad}<node type=\"${esc(node.type)}\"${attrs}/>`\n if (VOID_TAGS.has(tag)) return `${pad}<${tag}${attrs}/>`\n\n const kids = node.content ?? []\n if (kids.some(isBlock)) {\n const inner = kids.map((c) => nodeToXml(c, depth + 1)).join(\"\\n\")\n return `${pad}<${tag}${attrs}>\\n${inner}\\n${pad}</${tag}>`\n }\n return `${pad}<${tag}${attrs}>${inlineToXml(kids)}</${tag}>`\n}\n\n/** 把一整份 ProseMirror doc JSON 序列化成 LiteXML。 */\nexport function docToXml(doc: JSONContent): string {\n return (doc.content ?? []).map((n) => nodeToXml(n, 0)).join(\"\\n\")\n}\n\n/* ----------------------------- 反序列化 ----------------------------- */\n\n/**\n * XML 解析器由调用方注入 —— 浏览器传原生 `DOMParser`,Node 传 `@xmldom/xmldom` 的。\n * 同 `docx/parse.ts` 的做法,目的一样:让这层能在 Node 里跑测试。\n * 省略时自动取 `globalThis.DOMParser`,所以浏览器侧零配置。\n */\nexport interface LiteXmlParseOptions {\n DOMParser?: { new (): { parseFromString(source: string, mimeType: string): Document } }\n}\n\nfunction coerce(name: string, raw: string): unknown {\n if (NUM_ATTRS.has(name)) {\n const n = Number(raw)\n return Number.isNaN(n) ? raw : n\n }\n if (BOOL_ATTRS.has(name)) return raw === \"true\" || raw === \"\"\n if (name === \"colwidth\")\n return raw\n .split(\",\")\n .map(Number)\n .filter((n) => !Number.isNaN(n))\n return raw\n}\n\n/**\n * `@xmldom/xmldom` 没实现 `Element.children`(DOM4),`NamedNodeMap` 也不保证可迭代,\n * 所以这里一律走 `childNodes` / `item(i)` 这套 DOM Level 1 API。\n */\nfunction childElements(el: Element): Element[] {\n const out: Element[] = []\n const kids = el.childNodes\n for (let i = 0; i < kids.length; i++) {\n const n = kids.item(i)\n if (n && n.nodeType === 1) out.push(n as Element)\n }\n return out\n}\n\nfunction xmlAttrsToPm(el: Element, skip: ReadonlySet<string> = new Set()): Record<string, unknown> {\n const attrs: Record<string, unknown> = {}\n const list = el.attributes\n for (let i = 0; i < list.length; i++) {\n const a = list.item(i)\n if (!a) continue\n const name = ATTR_UNALIAS[a.name] ?? a.name\n if (skip.has(name)) continue\n attrs[name] = coerce(name, a.value)\n }\n return attrs\n}\n\nfunction xmlInlineToPm(el: Element): JSONContent[] {\n const out: JSONContent[] = []\n const kids = el.childNodes\n for (let i = 0; i < kids.length; i++) {\n const child = kids.item(i)\n if (!child) continue\n if (child.nodeType === 3) {\n if (child.nodeValue) out.push({ type: \"text\", text: child.nodeValue })\n continue\n }\n if (child.nodeType !== 1) continue\n const childEl = child as Element\n const tag = childEl.tagName.toLowerCase()\n\n if (tag === \"br\") {\n out.push({ type: \"hardBreak\" })\n continue\n }\n if (tag === \"node\") {\n const type = childEl.getAttribute(\"type\")\n if (!type) throw new Error(\"<node> 必须带 type 属性\")\n out.push({ type, attrs: xmlAttrsToPm(childEl, new Set([\"type\"])) })\n continue\n }\n\n let mark: { type: string; attrs?: Record<string, unknown> } | null = null\n if (MARK_BY_TAG[tag]) mark = { type: MARK_BY_TAG[tag] }\n else if (tag === \"a\")\n mark = { type: \"link\", attrs: { href: childEl.getAttribute(\"href\") ?? \"\" } }\n else if (tag === \"mark\")\n mark = { type: \"highlight\", attrs: { color: childEl.getAttribute(\"color\") ?? null } }\n else if (tag === \"color\")\n mark = { type: \"textStyle\", attrs: { color: childEl.getAttribute(\"v\") ?? null } }\n\n const inner = xmlInlineToPm(childEl)\n if (!mark) {\n out.push(...inner)\n continue\n }\n for (const t of inner) {\n if (t.type === \"text\") t.marks = [...(t.marks ?? []), mark]\n out.push(t)\n }\n }\n return out\n}\n\nexport function xmlElToPm(el: Element): JSONContent {\n const tag = el.tagName.toLowerCase()\n\n if (tag === \"node\") {\n const type = el.getAttribute(\"type\")\n if (!type) throw new Error(\"<node> 必须带 type 属性\")\n return { type, attrs: xmlAttrsToPm(el, new Set([\"type\"])) }\n }\n\n const hm = /^h([1-6])$/.exec(tag)\n if (hm) {\n return {\n type: \"heading\",\n attrs: { level: Number(hm[1]), ...xmlAttrsToPm(el) },\n content: xmlInlineToPm(el),\n }\n }\n\n const type = TYPE_BY_TAG[tag]\n if (!type) {\n throw new Error(\n `未知标签 <${tag}>。可用:${Object.values(NODE_TAG).join(\" \")} h1-h6 node,` +\n `内联:${Object.values(MARK_TAG).join(\" \")} a mark color br`,\n )\n }\n if (READONLY_TAGS.has(tag)) {\n throw new Error(`<${tag}> 由扩展自动维护,不能直接写入`)\n }\n\n const attrs = xmlAttrsToPm(el)\n if (VOID_TAGS.has(tag)) return { type, attrs }\n\n const blockKids = childElements(el).filter((c) => {\n const t = c.tagName.toLowerCase()\n return Boolean(TYPE_BY_TAG[t]) || /^h[1-6]$/.test(t)\n })\n\n if (blockKids.length > 0) {\n return { type, attrs, content: blockKids.map(xmlElToPm) }\n }\n const inline = xmlInlineToPm(el)\n // 空块不带 content 键,而不是 content: undefined —— 后者会让 deepStrictEqual\n // 之类的结构比较把「空段落」和「空段落」判成不相等。\n return inline.length ? { type, attrs, content: inline } : { type, attrs }\n}\n\n/** 把一段 LiteXML 片段(可以是多个平级块)解析成 ProseMirror JSON 数组。 */\nexport function parseXmlFragment(xml: string, opts: LiteXmlParseOptions = {}): JSONContent[] {\n const g = globalThis as unknown as { DOMParser?: LiteXmlParseOptions[\"DOMParser\"] }\n const Parser = opts.DOMParser ?? g.DOMParser\n if (!Parser) {\n throw new Error(\n \"没有可用的 XML 解析器:浏览器外请通过 opts.DOMParser 注入(如 @xmldom/xmldom)\",\n )\n }\n let doc: Document\n try {\n doc = new Parser().parseFromString(`<root>${xml}</root>`, \"text/xml\")\n } catch (e) {\n throw new Error(`XML 解析失败:${String((e as Error).message ?? e).slice(0, 200)}`)\n }\n const err = doc.getElementsByTagName(\"parsererror\")[0]\n if (err) throw new Error(`XML 解析失败:${err.textContent?.slice(0, 200)}`)\n const root = doc.documentElement\n if (!root) throw new Error(\"XML 解析失败:没有根元素\")\n return childElements(root).map(xmlElToPm)\n}\n\n/* ------------------------------ 写入合并 ------------------------------ */\n\n/**\n * LiteXML 是**有损投影**。直接用解析结果整块替换会把它表达不了的属性静默抹掉\n * (= 「AI 改一个词顺手毁排版」)。所以 modify 一律以原节点 attrs 为底做合并,\n * 只让 XML 里真的出现过的键覆盖。\n *\n * 已验证的用例:对带 `lang=\"typescript\"` 的代码块用不带 lang 的 XML 做 modify,\n * 内容改了、lang 保住。\n */\nexport function mergeParsedNode(\n originalAttrs: Record<string, unknown>,\n parsed: JSONContent,\n): JSONContent {\n const incoming = Object.fromEntries(\n Object.entries(parsed.attrs ?? {}).filter(([, v]) => v !== null && v !== undefined),\n )\n return { ...parsed, attrs: { ...originalAttrs, ...incoming } }\n}\n","/**\n * doc-runtime 的操作层:一组 `(editor, args) => result` 的函数。\n *\n * 纪律:\n * - **寻址在执行的那一瞬间才解析**(每个函数自己现查 id → pos),所以没有\n * 「写后索引失效」—— 调用方不需要倒序处理,也不需要每改一处就重读一遍。\n * 这条同时写进了工具 description,因为模型带着 Google Docs / 腾讯文档那套\n * 条件反射,不明说它会自作聪明。\n * - 这层**不碰 DOM、不做高亮**。要闪烁提示的话,看返回值里的 id 自己去做\n * (DocRuntime 就是这么干的)—— 操作层保持可测。\n */\nimport type { Editor, JSONContent } from \"@tiptap/core\"\nimport type { Node as PMNode } from \"@tiptap/pm/model\"\n\nimport {\n FORMATTABLE,\n type FormattableMark,\n type LiteXmlParseOptions,\n mergeParsedNode,\n NODE_TAG,\n parseXmlFragment,\n READONLY_TAGS,\n} from \"./litexml.ts\"\n\n/* ================================ 定位 ================================ */\n\nexport interface NodeHit {\n node: PMNode\n pos: number\n}\n\nexport function findById(editor: Editor, id: string): NodeHit | null {\n let hit: NodeHit | null = null\n editor.state.doc.descendants((node, pos) => {\n if (hit) return false\n if (node.attrs?.id === id) {\n hit = { node, pos }\n return false\n }\n return true\n })\n return hit\n}\n\n/** 表格单元格用 (表格 id, row, col) 定位 —— 结构坐标,不是 position。 */\nfunction findCell(editor: Editor, tableId: string, row: number, col: number) {\n const t = findById(editor, tableId)\n if (!t) throw new Error(`找不到表格 id=\"${tableId}\"`)\n if (t.node.type.name !== \"table\")\n throw new Error(`id=\"${tableId}\" 不是表格,是 ${t.node.type.name}`)\n // 必须先自己界检:PM 的 Node.child() 越界是**抛 RangeError**,不是返回 undefined。\n // 写成 `const n = child(i); if (!n) throw ...` 那条友好报错永远执行不到,\n // 模型拿到的是一句裸的 \"Index 9 out of range for <tableRow(...)>\" —— 既没告诉它\n // 表格实际多大,还把整棵子树 dump 进了上下文。\n if (row < 0 || row >= t.node.childCount)\n throw new Error(`表格只有 ${t.node.childCount} 行,取不到第 ${row} 行(0-based)`)\n const rowNode = t.node.child(row)\n if (col < 0 || col >= rowNode.childCount)\n throw new Error(`第 ${row} 行只有 ${rowNode.childCount} 列,取不到第 ${col} 列(0-based)`)\n const cellNode = rowNode.child(col)\n // 累加求 cell 的绝对位置\n let pos = t.pos + 1\n for (let r = 0; r < row; r++) pos += t.node.child(r).nodeSize\n pos += 1\n for (let c = 0; c < col; c++) pos += rowNode.child(c).nodeSize\n return { node: cellNode, pos, table: t }\n}\n\n/**\n * 把「块内 textContent 的字符偏移」映射成文档 position。\n *\n * 不能直接用 `pos + 1 + offset`:块里若有内联原子节点(mention / emoji / 公式 /\n * hardBreak),它们在 position 上各占 1,在 textContent 里却贡献 0 个字符,\n * 两套坐标就错开了。走一遍 text 子节点建映射表才是准的。\n */\nfunction textOffsetMap(node: PMNode, pos: number) {\n const segs: { textStart: number; from: number; len: number }[] = []\n let textOffset = 0\n node.descendants((child, childPos) => {\n if (child.isText) {\n const len = child.text?.length ?? 0\n segs.push({ textStart: textOffset, from: pos + 1 + childPos, len })\n textOffset += len\n }\n return true\n })\n\n /**\n * 起点和终点的边界判定必须分开。\n *\n * 一个正好落在段边界上的偏移是有歧义的:它既是前一段的结尾,也是后一段的开头。\n * 对「abc<br/>def」求 \"def\" 的起点(偏移 3),若按 `<=` 判会命中第一段的末尾,\n * 算出来的 position 指向那个 <br/> —— 于是替换范围把硬换行一起吞掉。\n * 起点要严格落在段**内部**(`<`),终点才允许贴在段尾(`<=`)。\n */\n return {\n start(offset: number): number {\n for (const s of segs) {\n if (offset < s.textStart + s.len) return s.from + (offset - s.textStart)\n }\n const last = segs[segs.length - 1]\n return last ? last.from + last.len : pos + 1\n },\n end(offset: number): number {\n for (const s of segs) {\n if (offset <= s.textStart + s.len) return s.from + (offset - s.textStart)\n }\n return pos + 1 + node.content.size\n },\n }\n}\n\n/* ============================== 结构化编辑 ============================== */\n\nexport type ModifyOperation =\n | { action: \"insert\"; afterId: string; litexml: string; beforeId?: never; id?: never }\n | { action: \"insert\"; beforeId: string; litexml: string; afterId?: never; id?: never }\n | { action: \"remove\"; id: string; litexml?: never; afterId?: never; beforeId?: never }\n | { action: \"modify\"; litexml: string | string[]; id?: never; afterId?: never; beforeId?: never }\n\nexport interface ModifyResultItem {\n action: string\n success: boolean\n error?: string\n id?: string\n anchor?: string\n count?: number\n modifiedIds?: string[]\n}\n\nexport interface ModifyNodesResult {\n results: ModifyResultItem[]\n successCount: number\n totalCount: number\n /** 本批实际改动到的块 id,调用方可拿去做高亮。 */\n touchedIds: string[]\n}\n\nexport function applyOperations(\n editor: Editor,\n operations: ModifyOperation[],\n parseOpts: LiteXmlParseOptions = {},\n): ModifyNodesResult {\n const results: ModifyResultItem[] = []\n const touchedIds: string[] = []\n\n for (const op of operations) {\n try {\n if (op.action === \"remove\") {\n const hit = findById(editor, op.id)\n if (!hit) throw new Error(`找不到 id=\"${op.id}\"`)\n editor\n .chain()\n .command(({ tr }) => {\n tr.delete(hit.pos, hit.pos + hit.node.nodeSize)\n return true\n })\n .run()\n results.push({ action: \"remove\", success: true, id: op.id })\n continue\n }\n\n if (op.action === \"insert\") {\n const anchorId = op.afterId ?? op.beforeId\n if (!anchorId) throw new Error(\"insert 必须给 afterId 或 beforeId\")\n const hit = findById(editor, anchorId)\n if (!hit) throw new Error(`找不到锚点 id=\"${anchorId}\"`)\n const nodes = parseXmlFragment(op.litexml, parseOpts)\n const at = op.afterId ? hit.pos + hit.node.nodeSize : hit.pos\n editor\n .chain()\n .insertContentAt(at, nodes as JSONContent[])\n .run()\n results.push({ action: \"insert\", success: true, anchor: anchorId, count: nodes.length })\n continue\n }\n\n if (op.action === \"modify\") {\n const xmls = Array.isArray(op.litexml) ? op.litexml : [op.litexml]\n const modifiedIds: string[] = []\n for (const xml of xmls) {\n for (const parsed of parseXmlFragment(xml, parseOpts)) {\n const id = parsed.attrs?.id as string | undefined\n if (!id) throw new Error(\"modify 的 litexml 必须带 id 属性\")\n const hit = findById(editor, id)\n if (!hit) throw new Error(`找不到 id=\"${id}\"`)\n editor\n .chain()\n .command(({ tr, state }) => {\n // LiteXML 有损,整块替换会静默抹掉它表达不了的属性。见 mergeParsedNode。\n const merged = mergeParsedNode(hit.node.attrs, parsed)\n tr.replaceWith(\n hit.pos,\n hit.pos + hit.node.nodeSize,\n state.schema.nodeFromJSON(merged),\n )\n return true\n })\n .run()\n modifiedIds.push(id)\n touchedIds.push(id)\n }\n }\n results.push({ action: \"modify\", success: true, count: xmls.length, modifiedIds })\n continue\n }\n\n throw new Error(`未知 action: ${(op as { action: string }).action}`)\n } catch (e) {\n results.push({\n action: (op as { action: string }).action,\n success: false,\n error: String((e as Error).message ?? e),\n })\n }\n }\n\n return {\n results,\n successCount: results.filter((r) => r.success).length,\n totalCount: results.length,\n touchedIds,\n }\n}\n\n/* ============================== 文本替换 ============================== */\n\nexport interface ReplaceTextArgs {\n searchText: string\n newText: string\n /** 限定生效范围;省略则全文 */\n nodeIds?: string[]\n /** 默认 false,只替换第一处 */\n replaceAll?: boolean\n}\n\nexport interface ReplaceTextResult {\n replacementCount: number\n modifiedNodeIds: string[]\n}\n\nexport function replaceText(\n editor: Editor,\n { searchText, newText, nodeIds, replaceAll = false }: ReplaceTextArgs,\n): ReplaceTextResult {\n if (!searchText) throw new Error(\"searchText 不能为空\")\n\n const targets: { node: PMNode; pos: number; id?: string }[] = []\n editor.state.doc.descendants((node, pos) => {\n if (!node.isTextblock) return true\n if (nodeIds?.length && !nodeIds.includes(node.attrs?.id)) return true\n targets.push({ node, pos, id: node.attrs?.id })\n return true\n })\n\n /**\n * 只替换命中的那一段,不是整块重写。\n *\n * 原实现是 `insertText(整块新文本, blockStart, blockEnd)` —— 那会把块内所有\n * 内联标记和原子节点一起抹平(改一个词,整段的加粗/链接/mention 全没了)。\n * 而工具 description 恰恰在教模型「优先用 replace_text,别整块重写」,\n * 这个实现会让那条建议反过来害人。\n */\n const replaceInBlock = (t: { node: PMNode; pos: number; id?: string }): number => {\n const text = t.node.textContent\n const offsets: number[] = []\n let i = text.indexOf(searchText)\n while (i !== -1) {\n offsets.push(i)\n if (!replaceAll) break\n i = text.indexOf(searchText, i + searchText.length)\n }\n if (!offsets.length) return 0\n\n const map = textOffsetMap(t.node, t.pos)\n // 块内也要倒序,否则前一处替换会挪动后一处的 position\n for (const off of offsets.reverse()) {\n const from = map.start(off)\n const to = map.end(off + searchText.length)\n editor\n .chain()\n .command(({ tr }) => {\n tr.insertText(newText, from, to)\n return true\n })\n .run()\n }\n return offsets.length\n }\n\n // 单点替换走文档顺序取第一处。\n // 原实现对 targets 统一 reverse 后遍历再 break,于是 replaceAll:false 命中的是\n // 文档里**最后**一处,和 description 说的「只替换第一处」正好相反。\n // 单点替换不存在 position 挪动问题,不需要倒序。\n if (!replaceAll) {\n const first = targets.find((t) => t.node.textContent.includes(searchText))\n if (!first) return { replacementCount: 0, modifiedNodeIds: [] }\n const n = replaceInBlock(first)\n return { replacementCount: n, modifiedNodeIds: first.id ? [first.id] : [] }\n }\n\n // 全量替换:跨块必须倒序,否则前面块的改动会挪动后面块的 position\n const modified: string[] = []\n let count = 0\n for (const t of [...targets].reverse()) {\n if (!t.node.textContent.includes(searchText)) continue\n count += replaceInBlock(t)\n if (t.id) modified.push(t.id)\n }\n modified.reverse() // 回到文档顺序,返回值别让调用方看见我们的遍历方向\n return { replacementCount: count, modifiedNodeIds: modified }\n}\n\n/* ============================== 行内格式 ============================== */\n\nexport interface FormatTextArgs {\n nodeId: string\n searchText: string\n marks: FormattableMark[]\n /** true 则移除这些标记而不是施加,默认 false */\n remove?: boolean\n /** 块内第几处匹配,从 1 开始,默认 1 */\n occurrence?: number\n}\n\nexport function formatText(\n editor: Editor,\n { nodeId, searchText, marks, remove = false, occurrence = 1 }: FormatTextArgs,\n) {\n const bad = (marks ?? []).filter((m) => !FORMATTABLE.includes(m))\n if (bad.length) throw new Error(`不支持的标记 ${bad.join(\",\")};可用:${FORMATTABLE.join(\" / \")}`)\n\n const hit = findById(editor, nodeId)\n if (!hit) throw new Error(`找不到 id=\"${nodeId}\"`)\n\n const text = hit.node.textContent\n let idx = -1\n for (let n = 0; n < occurrence; n++) {\n idx = text.indexOf(searchText, idx + 1)\n if (idx === -1) break\n }\n if (idx === -1)\n throw new Error(\n `块 ${nodeId} 里找不到第 ${occurrence} 处 \"${searchText}\"(内容:${text.slice(0, 80)})`,\n )\n\n const map = textOffsetMap(hit.node, hit.pos)\n const from = map.start(idx)\n const to = map.end(idx + searchText.length)\n\n let chain = editor.chain().setTextSelection({ from, to })\n for (const m of marks) chain = remove ? chain.unsetMark(m) : chain.setMark(m)\n chain.run()\n\n return { nodeId, marks, removed: remove, matched: searchText }\n}\n\n/* ================================ 表格 ================================ */\n\nexport type TableAction =\n | \"set_cells\"\n | \"insert_row_after\"\n | \"insert_row_before\"\n | \"insert_col_after\"\n | \"insert_col_before\"\n | \"delete_row\"\n | \"delete_col\"\n | \"toggle_header_row\"\n | \"merge_cells\"\n | \"split_cell\"\n\nexport interface TableEditArgs {\n tableId: string\n action: TableAction\n row?: number\n col?: number\n values?: { row: number; col: number; text: string }[]\n}\n\nconst TABLE_COMMANDS = {\n insert_row_after: \"addRowAfter\",\n insert_row_before: \"addRowBefore\",\n insert_col_after: \"addColumnAfter\",\n insert_col_before: \"addColumnBefore\",\n delete_row: \"deleteRow\",\n delete_col: \"deleteColumn\",\n toggle_header_row: \"toggleHeaderRow\",\n merge_cells: \"mergeCells\",\n split_cell: \"splitCell\",\n} as const\n\nexport function tableEdit(editor: Editor, { tableId, action, row, col, values }: TableEditArgs) {\n const t = findById(editor, tableId)\n if (!t) throw new Error(`找不到表格 id=\"${tableId}\"`)\n\n if (action === \"set_cells\") {\n if (!Array.isArray(values)) throw new Error(\"set_cells 需要 values: [{row, col, text}]\")\n // 倒序写,避免前面的改动挪动后面的 pos\n const sorted = [...values].sort((a, b) => b.row - a.row || b.col - a.col)\n for (const v of sorted) {\n const cell = findCell(editor, tableId, v.row, v.col)\n const para = cell.node.firstChild\n const from = cell.pos + 1 + 1\n const to = from + (para ? para.content.size : 0)\n editor\n .chain()\n .command(({ tr }) => {\n tr.insertText(String(v.text), from, to)\n return true\n })\n .run()\n }\n return { tableId, updated: values.length }\n }\n\n // 结构性操作必须显式给锚点。之前省略 row/col 时兜底选了表头单元格,\n // 于是 insert_row_after 把新行插在了第 1 行 —— codex 实测撞到过这个错位。\n // 宁可报错也不要猜:错误信息本身就是给模型的教学。\n if (row == null || col == null) {\n throw new Error(\n `${action} 必须显式指定 row 和 col(0-based,表头是第 0 行)作为锚点单元格。` +\n `该表格共 ${t.node.childCount} 行。例如要在最后一行后面加一行:` +\n `row=${t.node.childCount - 1}, col=0`,\n )\n }\n\n const cmd = TABLE_COMMANDS[action as keyof typeof TABLE_COMMANDS]\n if (!cmd)\n throw new Error(\n `未知 action: ${action};可用 ${Object.keys(TABLE_COMMANDS).join(\" / \")} / set_cells`,\n )\n\n const cell = findCell(editor, tableId, row, col)\n editor\n .chain()\n .setTextSelection(cell.pos + 2)\n .run()\n const chain = editor.chain().focus() as unknown as Record<string, () => { run(): boolean }>\n const ok = chain[cmd]().run()\n\n return { tableId, action, ok }\n}\n\n/* ================================ 只读 ================================ */\n\nexport interface FindHit {\n nodeId: string | null\n nodeType: string\n contextBefore: string\n match: string\n contextAfter: string\n}\n\nexport function findTextInDoc(editor: Editor, query: string, limit = 20) {\n if (!query) throw new Error(\"query 不能为空\")\n const hits: FindHit[] = []\n editor.state.doc.descendants((node) => {\n if (hits.length >= limit) return false\n if (!node.isTextblock) return true\n const text = node.textContent\n let i = text.indexOf(query)\n while (i !== -1 && hits.length < limit) {\n hits.push({\n nodeId: node.attrs?.id ?? null,\n nodeType: node.type.name,\n contextBefore: text.slice(Math.max(0, i - 30), i),\n match: query,\n contextAfter: text.slice(i + query.length, i + query.length + 30),\n })\n i = text.indexOf(query, i + query.length)\n }\n return true\n })\n return { hits, total: hits.length }\n}\n\nexport function getSelection(editor: Editor) {\n const { from, to, empty } = editor.state.selection\n if (empty) return { selection: null, note: \"本轮无选区,不要从历史推断\" }\n const blocks: { id: string; type: string }[] = []\n editor.state.doc.nodesBetween(from, to, (node) => {\n if (node.attrs?.id) blocks.push({ id: node.attrs.id, type: node.type.name })\n return true\n })\n return { selection: { text: editor.state.doc.textBetween(from, to, \"\\n\"), blocks } }\n}\n\n/**\n * 从**运行时 schema** 反射出来的能力清单,所以永远不会和实现漂移。\n * 模型不确定某个结构能不能写、该用什么标签时先查它。\n */\nexport function docSchema(editor: Editor) {\n const idTypes =\n (\n editor.extensionManager.extensions.find((e) => e.name === \"uniqueID\")?.options as\n | { types?: string[] }\n | undefined\n )?.types ?? []\n return {\n nodeTypes: Object.keys(editor.schema.nodes),\n markTypes: Object.keys(editor.schema.marks),\n litexmlTags: NODE_TAG,\n readonlyTags: [...READONLY_TAGS],\n idBearingTypes: idTypes,\n note:\n \"只有 idBearingTypes 里的节点带稳定 id,可被直接寻址。\" +\n \"表格单元格的结构性改动用 doc_table_edit 的 (tableId,row,col) 定位。\",\n }\n}\n\n/** 按节点类型点数,用来和导入源做对账。 */\nexport function docStats(editor: Editor) {\n const nodes: Record<string, number> = {}\n const marks: Record<string, number> = {}\n const headings: Record<string, number> = {}\n let textLength = 0\n\n editor.state.doc.descendants((n) => {\n nodes[n.type.name] = (nodes[n.type.name] ?? 0) + 1\n if (n.type.name === \"heading\") {\n const l = `h${n.attrs.level}`\n headings[l] = (headings[l] ?? 0) + 1\n }\n if (n.isText) {\n textLength += n.text?.length ?? 0\n for (const m of n.marks) marks[m.type.name] = (marks[m.type.name] ?? 0) + 1\n }\n return true\n })\n\n return { nodes, marks, headings, textLength, topLevelBlocks: editor.state.doc.childCount }\n}\n","/**\n * DocRuntime —— 包着一个 tiptap Editor 实例的结构化编辑面。\n *\n * **这层不知道 MCP 存在**,也不知道 HTTP、WebSocket、tool schema 存在。\n * 它只知道自己这个编辑器的 schema 怎么读、怎么改 —— 那本来就是编辑器包自己的事。\n * 工具定义和传输在 `@4399ywkf/editor-mcp`。\n *\n * 方法名刻意对齐 jizhi_ai 的 `@jizhi/editor-runtime`(Lexical 版):\n * `setEditor` / `isReady` / `getPageContent` / `modifyNodes` / `replaceText`。\n * 两套编辑器将来要能被同一套工具面驱动,形状不一致的话那张对照表就只是张表。\n * 我们比它多出来的是 tiptap 侧特有的:`formatText` / `tableEdit` / `getSchema`。\n */\nimport type { Editor } from \"@tiptap/core\"\n\nimport type { LiteXmlParseOptions } from \"./litexml.ts\"\nimport { docToXml } from \"./litexml.ts\"\nimport {\n applyOperations,\n docSchema,\n docStats,\n type FormatTextArgs,\n findTextInDoc,\n formatText,\n getSelection,\n type ModifyOperation,\n type ReplaceTextArgs,\n replaceText,\n type TableEditArgs,\n tableEdit,\n} from \"./operations.ts\"\n\n/**\n * 导入 / 导出的最小结构。\n *\n * 刻意不 `import type ... from \"../docx\"`:这层的纪律是「只认 tiptap Editor」,\n * 真去 import 会让 doc-runtime 依赖 docx 模块,跑 AI 工具面就得连带把\n * fflate 和整套 OOXML 序列化拖进来。这里只描述回调的形状 ——\n * 能力由宿主注册 ExportDocx / ImportDocx 提供,没注册就报错教用户怎么装。\n */\ninterface ExportMeta {\n stats: Record<string, number>\n warnings: string[]\n bytes: number\n}\ninterface ImportCtx {\n error?: Error\n recovered?: Record<string, number>\n warnings?: string[]\n setEditorContent: (content?: unknown) => void\n}\n\n/** base64 → 字节。浏览器里 atob 一定在(这层本来就只在浏览器跑) */\nfunction base64ToBytes(b64: string): Uint8Array {\n const bin = atob(b64.replace(/^data:[^,]*,/, \"\"))\n const out = new Uint8Array(bin.length)\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i)\n return out\n}\n\n/**\n * 文件名消毒:只留基名,挡掉路径分隔符和 `..`。\n *\n * 这个名字最终会到 hub 手里用于落盘,而它是**模型给的**。\n * hub 那边还会再校验一次目录边界 —— 两道,因为写文件不可逆。\n */\nfunction sanitizeFilename(name: string | undefined): string | null {\n if (!name) return null\n const base = name.split(/[/\\\\]/).pop()?.trim()\n if (!base || base === \".\" || base === \"..\") return null\n return /\\.docx$/i.test(base) ? base : `${base}.docx`\n}\n\nexport type DocReadFormat = \"xml\" | \"json\" | \"both\"\n\nexport interface GetPageContentArgs {\n /**\n * 默认 xml。json 是 ProseMirror 原生结构(无损但费 token,约 1.5-2.8 倍),\n * 只在怀疑 LiteXML 丢了信息时才用。\n */\n format?: DocReadFormat\n}\n\nexport interface DocRuntimeOptions {\n editor?: Editor | null\n /**\n * 写操作后对改动到的块做视觉提示。浏览器里默认闪一下(`.ai-flash`),\n * 传 `false` 关掉。Node / 测试环境里自动 no-op。\n */\n highlight?: ((id: string) => void) | false\n /** XML 解析器注入。浏览器里省略即可,会走全局 `DOMParser`。 */\n DOMParser?: LiteXmlParseOptions[\"DOMParser\"]\n}\n\n/** 默认高亮:给块加 `.ai-flash`,1.4s 后摘掉。样式见 ai-flash.scss。 */\nfunction domFlash(id: string): void {\n if (typeof document === \"undefined\") return\n requestAnimationFrame(() => {\n const sel = typeof CSS !== \"undefined\" && CSS.escape ? CSS.escape(id) : id\n const el = document.querySelector(`[data-id=\"${sel}\"], #${sel}`)\n if (!el) return\n el.classList.add(\"ai-flash\")\n setTimeout(() => el.classList.remove(\"ai-flash\"), 1400)\n })\n}\n\nexport class DocRuntime {\n private editor: Editor | null\n private readonly highlight: ((id: string) => void) | null\n private readonly parseOpts: LiteXmlParseOptions\n\n constructor(options: DocRuntimeOptions = {}) {\n this.editor = options.editor ?? null\n this.highlight =\n options.highlight === false ? null : (options.highlight ?? (domFlash as (id: string) => void))\n this.parseOpts = options.DOMParser ? { DOMParser: options.DOMParser } : {}\n }\n\n /** 编辑器实例就绪 / 卸载时调用。配合 `<NotionEditor onEditorReady>` 用。 */\n setEditor(editor: Editor | null): void {\n this.editor = editor\n }\n\n isReady(): boolean {\n return Boolean(this.editor && !this.editor.isDestroyed)\n }\n\n private use(): Editor {\n if (!this.editor) throw new Error(\"编辑器尚未就绪:先调 setEditor(editor)\")\n if (this.editor.isDestroyed) throw new Error(\"编辑器实例已销毁\")\n return this.editor\n }\n\n private flash(ids: Iterable<string>): void {\n if (!this.highlight) return\n for (const id of ids) this.highlight(id)\n }\n\n /* ------------------------------ 读 ------------------------------ */\n\n /** 读全文。要编辑之前必须先调它拿 id。 */\n getPageContent({ format = \"xml\" }: GetPageContentArgs = {}) {\n const editor = this.use()\n const out: { blockCount: number; xml?: string; json?: unknown } = {\n blockCount: editor.state.doc.childCount,\n }\n if (format === \"xml\" || format === \"both\") out.xml = docToXml(editor.getJSON())\n if (format === \"json\" || format === \"both\") out.json = editor.getJSON()\n return out\n }\n\n /** 运行时反射出的节点·标记·标签映射·哪些类型带 id。永不与实现漂移。 */\n getSchema() {\n return docSchema(this.use())\n }\n\n /** 按节点类型点数,用来和导入源做对账。 */\n getStats() {\n return docStats(this.use())\n }\n\n /** 检索,返回可直接回填给写工具的 nodeId。 */\n find(args: { query: string; limit?: number }) {\n return findTextInDoc(this.use(), args.query, args.limit)\n }\n\n /** 用户此刻的选区;无选区时显式声明「不要沿用历史」。 */\n getSelection() {\n return getSelection(this.use())\n }\n\n /* ------------------------------ 写 ------------------------------ */\n\n /** 块内文本替换(细粒度改动首选)。 */\n replaceText(args: ReplaceTextArgs) {\n const result = replaceText(this.use(), args)\n this.flash(result.modifiedNodeIds)\n return result\n }\n\n /** 对某段文字加/去 bold·italic·underline·strike·code·sup·sub(改格式首选)。 */\n formatText(args: FormatTextArgs) {\n const result = formatText(this.use(), args)\n this.flash([result.nodeId])\n return result\n }\n\n /** 结构化 insert / remove / modify,一次提交多个操作。 */\n modifyNodes(args: { operations: ModifyOperation[] }) {\n const result = applyOperations(this.use(), args.operations ?? [], this.parseOpts)\n this.flash(result.touchedIds)\n return result\n }\n\n /** 表格:增删行列、合并拆分、批量写值。 */\n tableEdit(args: TableEditArgs) {\n const result = tableEdit(this.use(), args)\n this.flash([args.tableId])\n return result\n }\n\n /* ---------------------------- 导入 / 导出 ---------------------------- */\n\n /**\n * 导出成 .docx,返回 base64。\n *\n * 走 `editor.commands.exportDocx` 而不是直接调 `serializeDocx`:页眉页脚的原始\n * 部件存在 `editor.storage.importDocx.section` 上,表格列宽的换算基准要量\n * `editor.view.dom` —— 这两样只有命令那条路会自动接上,绕过去就会丢页眉、\n * 并且把表格导得超出页面。\n *\n * base64 是**给传输层的**,不是给模型看的。hub 收到后落盘、只把路径回给模型;\n * 一份带图的 docx 几 MB,塞进上下文会直接把窗口撑爆。\n */\n exportDocx(args: { filename?: string } = {}): {\n filename: string\n base64: string\n bytes: number\n stats: Record<string, number>\n warnings: string[]\n } {\n const editor = this.use()\n const run = (editor.commands as Record<string, unknown>).exportDocx\n if (typeof run !== \"function\") {\n throw new Error(\n \"编辑器没装 ExportDocx 扩展:从 @4399ywkf/editor/docx 引入 ExportDocx,\" +\n \"通过 <NotionEditor extensions={[ExportDocx]}> 注册后再试\",\n )\n }\n\n let payload: { base64: string; meta: ExportMeta } | null = null\n ;(run as (o: unknown) => boolean)({\n exportType: \"string\", // base64\n onCompleteExport: (result: unknown, meta: ExportMeta) => {\n payload = { base64: String(result), meta }\n },\n })\n if (!payload) throw new Error(\"导出失败:exportDocx 没有回调(多半是序列化时抛了异常)\")\n\n const { base64, meta } = payload as { base64: string; meta: ExportMeta }\n return {\n filename: sanitizeFilename(args.filename) ?? \"document.docx\",\n base64,\n bytes: meta?.bytes ?? 0,\n stats: meta?.stats ?? {},\n warnings: meta?.warnings ?? [],\n }\n }\n\n /**\n * 把一份 .docx 灌进编辑器,**整篇替换**当前内容。\n *\n * 同样走命令:`ImportDocx` 会按宿主 schema 降级未知节点、量版心换算表格列宽、\n * 把页眉页脚记进 storage 供导出时写回。\n */\n importDocx(args: { base64: string }): Promise<{\n blockCount: number\n recovered: Record<string, number>\n warnings: string[]\n }> {\n const editor = this.use()\n const run = (editor.commands as Record<string, unknown>).importDocx\n if (typeof run !== \"function\") {\n throw new Error(\n \"编辑器没装 ImportDocx 扩展:从 @4399ywkf/editor/docx 引入 ImportDocx,\" +\n \"通过 <NotionEditor extensions={[ImportDocx]}> 注册后再试\",\n )\n }\n if (!args?.base64) throw new Error(\"importDocx 需要 base64(hub 会把 path 读成 base64 再转发)\")\n\n return new Promise((resolve, reject) => {\n // 命令同步返回 true,转换在微任务里完成 —— 必须等回调,否则拿到的是空结果\n ;(run as (o: unknown) => boolean)({\n file: base64ToBytes(args.base64),\n onImport: (ctx: ImportCtx) => {\n if (ctx.error) {\n reject(ctx.error)\n return\n }\n ctx.setEditorContent()\n resolve({\n blockCount: this.editor?.state.doc.childCount ?? 0,\n recovered: ctx.recovered ?? {},\n warnings: ctx.warnings ?? [],\n })\n },\n })\n })\n }\n\n /* ---------------------------- 统一入口 ---------------------------- */\n\n /**\n * 工具名 → 方法。给传输层(MCP 桥、agent executor)用的单一分发口,\n * 这样加一个工具只需要改这里,不需要每个传输各写一遍 switch。\n */\n async call(tool: string, args: Record<string, unknown> = {}): Promise<unknown> {\n switch (tool) {\n case \"doc_read\":\n return this.getPageContent(args as GetPageContentArgs)\n case \"doc_schema\":\n return this.getSchema()\n case \"doc_stats\":\n return this.getStats()\n case \"doc_find\":\n return this.find(args as { query: string; limit?: number })\n case \"doc_get_selection\":\n return this.getSelection()\n case \"doc_replace_text\":\n return this.replaceText(args as unknown as ReplaceTextArgs)\n case \"doc_format_text\":\n return this.formatText(args as unknown as FormatTextArgs)\n case \"doc_modify_nodes\":\n return this.modifyNodes(args as unknown as { operations: ModifyOperation[] })\n case \"doc_table_edit\":\n return this.tableEdit(args as unknown as TableEditArgs)\n case \"doc_export_docx\":\n return this.exportDocx(args as { filename?: string })\n case \"doc_import_docx\":\n return this.importDocx(args as unknown as { base64: string })\n default:\n throw new Error(`未知工具 ${tool}`)\n }\n }\n}\n"]}
|
package/dist/doc.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ArticleViewer, Audio, Button, CollabContext, CollabProvider, Column, Columns, DEFAULT_MAX_FILE_SIZES, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EditorConfigProvider, EditorContentArea, FileAttachment, FloatingElement, HIDE_FLOATING_META, LoadingSpinner, MAC_SYMBOLS, MAX_FILE_SIZE, MediaUploadButton, MediaUploadPlaceholder, NotionEditor, NotionEditorContent, EditorProvider as NotionEditorInner, PasteDropMedia, Popover, PopoverContent, PopoverTrigger, SR_ONLY, Separator, Spacer, Toolbar, ToolbarGroup, ToolbarSeparator, UiState, UserContext, UserProvider, Video, clamp, cn, defaultUiState, detectMediaKind, findNodeAtPosition, findNodePosition, findSelectionPosition, focusNextNode, formatShortcutKey, getAvatar, getElementOverflowPosition, getNodeDisplayName, getSelectedBlockNodes, getSelectedNodesOfType, getSelectionBoundingRect, getUrlParam, handleImageUpload, hasContentAbove, isAllowedUri, isExtensionAvailable, isMac, isMarkInSchema, isNodeInSchema, isNodeTypeSelected, isSelectionValid, isTextSelectionValid, isValidPosition, markHideFloatingOnNext, parseShortcutKeys, pickFile, removeEmptyParagraphs, resolveMaxSize, runMediaUpload, sanitizeUrl, selectCurrentBlockContent, selectNodeAndHideFloating, selectionWithinConvertibleTypes, updateNodesAttr, useCollab, useCollaboration, useComposedRef, useCursorVisibility, useEditorConfig, useElementRect, useFloatingElement, useFloatingToolbarVisibility, useIsBreakpoint, useIsomorphicLayoutEffect, useMenuNavigation, useOnClickOutside, useThrottledCallback, useTiptapEditor, useUiEditorState, use_ui_editor_state_default as useUiEditorStateDefault, useUnmount, useUser, useWindowSize } from './chunk-
|
|
1
|
+
export { ArticleViewer, Audio, Button, CollabContext, CollabProvider, Column, Columns, DEFAULT_MAX_FILE_SIZES, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EditorConfigProvider, EditorContentArea, FileAttachment, FloatingElement, HIDE_FLOATING_META, LoadingSpinner, MAC_SYMBOLS, MAX_FILE_SIZE, MediaUploadButton, MediaUploadPlaceholder, NotionEditor, NotionEditorContent, EditorProvider as NotionEditorInner, PasteDropMedia, Popover, PopoverContent, PopoverTrigger, SR_ONLY, Separator, Spacer, Toolbar, ToolbarGroup, ToolbarSeparator, UiState, UserContext, UserProvider, Video, clamp, cn, defaultUiState, detectMediaKind, findNodeAtPosition, findNodePosition, findSelectionPosition, focusNextNode, formatShortcutKey, getAvatar, getElementOverflowPosition, getNodeDisplayName, getSelectedBlockNodes, getSelectedNodesOfType, getSelectionBoundingRect, getUrlParam, handleImageUpload, hasContentAbove, isAllowedUri, isExtensionAvailable, isMac, isMarkInSchema, isNodeInSchema, isNodeTypeSelected, isSelectionValid, isTextSelectionValid, isValidPosition, markHideFloatingOnNext, parseShortcutKeys, pickFile, removeEmptyParagraphs, resolveMaxSize, runMediaUpload, sanitizeUrl, selectCurrentBlockContent, selectNodeAndHideFloating, selectionWithinConvertibleTypes, updateNodesAttr, useCollab, useCollaboration, useComposedRef, useCursorVisibility, useEditorConfig, useElementRect, useFloatingElement, useFloatingToolbarVisibility, useIsBreakpoint, useIsomorphicLayoutEffect, useMenuNavigation, useOnClickOutside, useThrottledCallback, useTiptapEditor, useUiEditorState, use_ui_editor_state_default as useUiEditorStateDefault, useUnmount, useUser, useWindowSize } from './chunk-ZRFOS52C.js';
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
function useScrolling(target, options = {}) {
|
package/dist/docx.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { Node, Extension, JSONContent } from '@tiptap/core';
|
|
2
2
|
|
|
3
|
-
declare const DocxField: Node<any, any>;
|
|
4
|
-
|
|
5
|
-
declare const DocxInk: Node<any, any>;
|
|
6
|
-
|
|
7
3
|
/**
|
|
8
4
|
* OOXML → tiptap JSONContent。
|
|
9
5
|
*
|
|
@@ -43,6 +39,59 @@ interface ParseDocxOptions {
|
|
|
43
39
|
prosemirrorMarks?: Record<string, string>;
|
|
44
40
|
/** 抽取文档默认样式为 CSS 字符串,对齐官方 `cssStyles` */
|
|
45
41
|
cssStyles?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* 宿主正文列的宽度(px),用来把表格列宽从「Word 页面」换算到「编辑器版心」。
|
|
44
|
+
*
|
|
45
|
+
* Word 的列宽虽然是绝对磅值,但它是**相对页面文本宽度**定出来的:本文档的
|
|
46
|
+
* 表格 tblW=9026dxa,而页面文本宽度(pgSz − 左右 pgMar)也正好是 9026dxa ——
|
|
47
|
+
* 在 Word 里它铺满一行。照搬绝对值塞进更宽的编辑器版心,就成了缩在左边的窄表。
|
|
48
|
+
* 给了这个值就按比例重新落位:满宽的表继续满宽,半宽的表继续占一半。
|
|
49
|
+
* 不给则保持 Word 的绝对磅值(Node 侧无从测量时的默认)。
|
|
50
|
+
*/
|
|
51
|
+
contentWidthPx?: number;
|
|
52
|
+
/**
|
|
53
|
+
* 宿主表格扩展的 `cellMinWidth`(px)。
|
|
54
|
+
*
|
|
55
|
+
* tiptap 渲染列宽时会做 `Math.max(colwidth, cellMinWidth)`,但表格总宽仍按
|
|
56
|
+
* 原始 colwidth 算 —— 于是窄列被顶宽、表格撑破、列比例还变了形。
|
|
57
|
+
* 告诉我们这个下限,就能提前把宽度摊匀,不让读端去顶。
|
|
58
|
+
*/
|
|
59
|
+
minColumnWidthPx?: number;
|
|
60
|
+
}
|
|
61
|
+
interface DocxSectionRef {
|
|
62
|
+
kind: 'header' | 'footer';
|
|
63
|
+
/** `default` | `first` | `even` */
|
|
64
|
+
type: string;
|
|
65
|
+
/** 原 sectPr 里的 r:id */
|
|
66
|
+
rid: string;
|
|
67
|
+
/** 包内路径,如 `word/header1.xml` */
|
|
68
|
+
path: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 节属性(页眉页脚 + 页面几何),**原样**带出来。
|
|
72
|
+
*
|
|
73
|
+
* 为什么不解析成 JSONContent 再写回:编辑器没有页眉页脚这个概念,解析→重建
|
|
74
|
+
* 只会把我们看不懂的东西(域、图片、制表位、边框…)在往返中磨掉。这里存的是
|
|
75
|
+
* 原始字节和原始 XML,导出时塞回包里即可,磨不掉 —— 和 `docxInk` 存
|
|
76
|
+
* `strokesXml` 是同一个思路。
|
|
77
|
+
*/
|
|
78
|
+
interface DocxSection {
|
|
79
|
+
/**
|
|
80
|
+
* 原始 `<w:sectPr>` XML。导出时除了重写页眉页脚的 r:id,其余原样写回 ——
|
|
81
|
+
* 页面尺寸、页边距、页码格式、文档网格、首页不同都在里面。
|
|
82
|
+
*/
|
|
83
|
+
sectPrXml: string | null;
|
|
84
|
+
refs: DocxSectionRef[];
|
|
85
|
+
/** 页眉页脚部件本身 + 各自的 .rels + 它们引用到的媒体,键是包内路径 */
|
|
86
|
+
files: Record<string, Uint8Array>;
|
|
87
|
+
/**
|
|
88
|
+
* 原始 `word/settings.xml`。
|
|
89
|
+
*
|
|
90
|
+
* 和页眉直接相关:`evenAndOddHeaders` 决定奇偶页是否用不同页眉,丢了它
|
|
91
|
+
* 奇偶页眉就失效。另外 `compatSetting compatibilityMode` 缺失会让 Word
|
|
92
|
+
* 按兼容模式打开文档(标题栏挂「兼容模式」,排版规则也退回旧版)。
|
|
93
|
+
*/
|
|
94
|
+
settingsXml: string | null;
|
|
46
95
|
}
|
|
47
96
|
interface ParseDocxResult {
|
|
48
97
|
doc: Record<string, unknown>;
|
|
@@ -51,9 +100,19 @@ interface ParseDocxResult {
|
|
|
51
100
|
warnings: string[];
|
|
52
101
|
/** `cssStyles: true` 时给出的文档默认样式 */
|
|
53
102
|
css?: string;
|
|
103
|
+
/** 默认页眉的结构化内容(供宿主展示;往返靠的是 `section`,不是它) */
|
|
104
|
+
header: Record<string, unknown> | null;
|
|
105
|
+
/** 默认页脚的结构化内容,同上 */
|
|
106
|
+
footer: Record<string, unknown> | null;
|
|
107
|
+
/** 节属性原件,交给导出侧原样写回 */
|
|
108
|
+
section: DocxSection;
|
|
54
109
|
}
|
|
55
110
|
declare function parseDocx(entries: DocxEntries, opts: ParseDocxOptions): ParseDocxResult;
|
|
56
111
|
|
|
112
|
+
declare const DocxField: Node<any, any>;
|
|
113
|
+
|
|
114
|
+
declare const DocxInk: Node<any, any>;
|
|
115
|
+
|
|
57
116
|
/**
|
|
58
117
|
* tiptap JSONContent → .docx(OOXML)。
|
|
59
118
|
*
|
|
@@ -64,6 +123,7 @@ declare function parseDocx(entries: DocxEntries, opts: ParseDocxOptions): ParseD
|
|
|
64
123
|
* `docxInk` 写回 `w14:contentPart` + 位图回退 —— 这两样在导入时被保住,
|
|
65
124
|
* 导出时才有东西可写。
|
|
66
125
|
*/
|
|
126
|
+
|
|
67
127
|
interface SerializeOptions {
|
|
68
128
|
/** 把图片 src 换成字节。返回 null 则该图片跳过并记警告 */
|
|
69
129
|
resolveImage?: (src: string) => Uint8Array | null;
|
|
@@ -74,6 +134,25 @@ interface SerializeOptions {
|
|
|
74
134
|
};
|
|
75
135
|
/** 逐段落覆盖,对齐官方 paragraphOverrides */
|
|
76
136
|
paragraphOverrides?: (node: Node_) => Record<string, string> | undefined;
|
|
137
|
+
/**
|
|
138
|
+
* 导入时带出来的节属性(`ParseDocxResult.section`),原样写回。
|
|
139
|
+
*
|
|
140
|
+
* 编辑器渲染不了页眉页脚,但只要把原始部件塞回包里,一趟往返就不会丢 ——
|
|
141
|
+
* 连同页面尺寸、页边距、页码格式、文档网格这些 sectPr 上的东西一起。
|
|
142
|
+
* 不给则退回默认的 A4 + 2.54cm 页边距,且没有页眉页脚。
|
|
143
|
+
*/
|
|
144
|
+
section?: DocxSection;
|
|
145
|
+
/**
|
|
146
|
+
* 列宽所依据的编辑器版心宽度(px)—— 导入侧 `contentWidthPx` 的**逆变换**。
|
|
147
|
+
*
|
|
148
|
+
* 导入把 Word 的列宽按「占页面文本宽度的比例」重新落到了版心上,导出必须按
|
|
149
|
+
* 同样的比例还回去。只做单向的后果:708px 的表格被当成 708×15 = 10620 dxa 写出去,
|
|
150
|
+
* 而 A4 的页面文本宽度只有 9026 —— 表格在 Word 里冲出右边距、最后一列被切掉。
|
|
151
|
+
*
|
|
152
|
+
* 不给的话按 96dpi 直译(1px = 15dxa),但会**兜底裁到页面文本宽度以内**,
|
|
153
|
+
* 保证再怎么样也不会溢出页面。
|
|
154
|
+
*/
|
|
155
|
+
contentWidthPx?: number;
|
|
77
156
|
}
|
|
78
157
|
interface SerializeResult {
|
|
79
158
|
/** docx 包内的所有条目,交给 zip 打包 */
|
|
@@ -85,8 +164,20 @@ type Node_ = Record<string, any>;
|
|
|
85
164
|
declare function serializeDocx(doc: Node_, opts?: SerializeOptions): SerializeResult;
|
|
86
165
|
|
|
87
166
|
type ExportType = 'blob' | 'buffer' | 'string';
|
|
167
|
+
/** 导出的伴随信息。官方回调只给结果本身,统计和警告拿不到 —— 这里作为第二个参数补上 */
|
|
168
|
+
interface ExportDocxMeta {
|
|
169
|
+
stats: Record<string, number>;
|
|
170
|
+
warnings: string[];
|
|
171
|
+
/** 未压缩的字节数 */
|
|
172
|
+
bytes: number;
|
|
173
|
+
}
|
|
88
174
|
interface ExportDocxOptions extends SerializeOptions {
|
|
89
|
-
|
|
175
|
+
/**
|
|
176
|
+
* 导出完成回调。第一个参数的形状由 `exportType` 决定,对齐官方。
|
|
177
|
+
* 第二个参数是本扩展多给的统计与警告 —— 官方回调只给结果,
|
|
178
|
+
* 调用方拿不到「导出时丢了什么」,而那恰恰是最该看的。
|
|
179
|
+
*/
|
|
180
|
+
onCompleteExport: ((result: Blob | Uint8Array | string, meta: ExportDocxMeta) => void) | null;
|
|
90
181
|
exportType: ExportType;
|
|
91
182
|
/** 诊断级别,同导入侧 */
|
|
92
183
|
verbose: number;
|
|
@@ -146,6 +237,19 @@ interface ImportDocxOptions {
|
|
|
146
237
|
preserveUnsupported: boolean;
|
|
147
238
|
/** 是否注入浮动定位所需样式,默认 true */
|
|
148
239
|
injectStyles: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* 表格列宽的换算基准。
|
|
242
|
+
*
|
|
243
|
+
* Word 的列宽是相对**页面文本宽度**定的:铺满一行的表格,其 tblW 就等于
|
|
244
|
+
* 页宽减左右页边距。照搬这个绝对值塞进编辑器版心(往往更宽),表格就缩在
|
|
245
|
+
* 左边不铺满 —— 也就是「Word 里是自适应的,导进来却不是」。
|
|
246
|
+
*
|
|
247
|
+
* - `'auto'`(默认):导入时量一下编辑器正文列的实际宽度,按比例重新落位。
|
|
248
|
+
* 满宽的表继续满宽,半宽的表继续占一半。
|
|
249
|
+
* - 数字:直接用这个宽度(px)当基准,SSR / 测试等量不到 DOM 的场景用。
|
|
250
|
+
* - `null`:不换算,保留 Word 的绝对磅值。
|
|
251
|
+
*/
|
|
252
|
+
tableWidthBasis: number | 'auto' | null;
|
|
149
253
|
}
|
|
150
254
|
/** onImport 回调拿到的上下文,字段对齐官方 */
|
|
151
255
|
interface ImportDocxContext {
|
|
@@ -159,8 +263,19 @@ interface ImportDocxContext {
|
|
|
159
263
|
warnings: string[];
|
|
160
264
|
/** cssStyles:true 时的文档默认样式 */
|
|
161
265
|
css?: string;
|
|
266
|
+
/** 默认页眉的结构化内容。供宿主展示 —— 往返靠的是 `section`,不是它 */
|
|
162
267
|
header: JSONContent | null;
|
|
268
|
+
/** 默认页脚的结构化内容,同上 */
|
|
163
269
|
footer: JSONContent | null;
|
|
270
|
+
/**
|
|
271
|
+
* 节属性原件(页眉页脚部件 + 页面几何)。
|
|
272
|
+
*
|
|
273
|
+
* 编辑器渲染不了页眉页脚,所以它不进文档树;导出时把它交回
|
|
274
|
+
* `serializeDocx({ section })` 就能原样写回。同一个 editor 上同时挂了
|
|
275
|
+
* `ImportDocx` 和 `ExportDocx` 的话不用管 —— 导出侧会自动接上(见下)。
|
|
276
|
+
* 但它只活在内存里:刷新页面 / 换设备就没了,要跨会话往返得自己存。
|
|
277
|
+
*/
|
|
278
|
+
section: DocxSection;
|
|
164
279
|
footnotes: Record<string, JSONContent>;
|
|
165
280
|
endnotes: Record<string, JSONContent>;
|
|
166
281
|
}
|
|
@@ -181,4 +296,4 @@ declare module '@tiptap/core' {
|
|
|
181
296
|
}
|
|
182
297
|
declare const ImportDocx: Extension<ImportDocxOptions, any>;
|
|
183
298
|
|
|
184
|
-
export { type DocxEntries, DocxField, DocxInk, ExportDocx, type ExportDocxOptions, type ExportType, type ImageUploadConfig, ImportDocx, type ImportDocxCommandArgs, type ImportDocxContext, type ImportDocxOptions, type ParseDocxOptions, type ParseDocxResult, type SerializeOptions, type SerializeResult, docxFromJSON, downloadDocx, parseDocx, serializeDocx };
|
|
299
|
+
export { type DocxEntries, DocxField, DocxInk, type DocxSection, type DocxSectionRef, ExportDocx, type ExportDocxOptions, type ExportType, type ImageUploadConfig, ImportDocx, type ImportDocxCommandArgs, type ImportDocxContext, type ImportDocxOptions, type ParseDocxOptions, type ParseDocxResult, type SerializeOptions, type SerializeResult, docxFromJSON, downloadDocx, parseDocx, serializeDocx };
|