协作与审阅插件
六个插件,把编辑器变成一套实际可用的文档工作流:斜杠命令、@提及、修订跟踪、分线程批注、修订历史,以及基于 Yjs 的在线状态。全部包含在标准授权中——无需购买高级版本。
斜杠命令
在空行(或空白之后)输入 /,即可打开内联命令选择器。包含 15 种内置块(H1–H3、项目符号/编号列表、引用、代码、分隔线、表格、图片、链接、表情、今天的日期),以及所有已注册的 AI Toolkit 操作。
配置
{
slashCommandEnabled: true, // default when this plugin is loaded
slashCommandIncludeAi: true // pull aiToolkitActions into the menu
}API
editor.slashCommands.register({ id, label, keywords, run });
editor.slashCommands.remove(id);
editor.slashCommands.list();
editor.slashCommands.open(); / .close();@提及
一个触发字符框架,适用于 @、#、[[wiki]] 或任何自定义前缀。支持异步数据源(带防抖和加载状态)。生成不可编辑的原子“胶囊”——按退格键会删除整个标签。
注册触发字符
editor.mentions.register({
trigger: "@",
insertClass: "rte-mention-person",
search: function (query, done) {
fetch("/api/users?q=" + encodeURIComponent(query))
.then(r => r.json())
.then(done); // Array<{ id, name, color? }>
},
renderItem: function (user) { return user.name; },
renderInsert: function (user) { return "@" + user.name; }
});修订跟踪(人工建议模式)
Word 风格的建议模式。插入的内容以当前用户的颜色加下划线显示;删除的内容加删除线(在被接受之前不会真正删除)。连续的删除会合并为一个片段;在自己刚输入的插入内容中按退格键,会使该插入内容缩短。
配置
{
trackChangesEnabled: true,
currentUser: { id: "maya", name: "Maya Patel", color: "#9333ea" },
reviewCanDecide: (entry, action, user) => user.role === "editor"
}可在审阅抽屉中按作者接受/拒绝。使用 reviewCanDecide 执行您应用的审阅人策略;被拒绝的决定会让建议保持待定状态,并触发 review_decision_denied。被接受和被拒绝的建议都会保存 decidedBy,作为审计记录。它可以与 AI 建议并存——两者最终都存放在同一个 editor.reviewLedger 存储中。
修订历史
快照浏览器,带有沙盒预览 iframe 和基于 LCS 的逐行差异对比。支持手动快照或防抖的自动快照。默认存储在 localStorage 中,也可以 POST 到服务器端点。
配置
{
revisionHistoryEnabled: true,
revisionHistoryMaxEntries: 50,
revisionHistoryAutoSnapshotMs: 10000,
revisionHistoryUrl: "/api/revisions", // optional
revisionHistoryRequestHeaders: () => ({
"X-CSRF-Token": readCsrfToken()
}),
onRevisionHistorySyncError: ({ reason, status }) => {
reportSyncProblem(reason, status);
}
}请使用同源端点,配合您现有的会话和 CSRF 保护。标头值可以由一个函数提供,这样就能在请求时读取短期有效的防伪造令牌。不要在编辑器配置中放置长期有效的 API 密钥。
API
editor.revisionHistory.snapshot(label?, metadata?);
editor.revisionHistory.promptAndSnapshot(defaultLabel?); // native prompt + snapshot
editor.revisionHistory.rename(id, label);
editor.revisionHistory.list(); // all snapshots
editor.revisionHistory.listNamed(); // user-labeled only
editor.revisionHistory.diff(idA, idB); // { lines, oldText, newText }
editor.revisionHistory.restore(id);
editor.revisionHistory.delete(id);
editor.revisionHistory.openBrowser();Yjs 在线状态与并发输入
实时光标、在线头像、共享审阅台账。Yjs 是一个对等依赖——插件本身从不包含它。您需要自行加载 Yjs 和一个提供程序(WebSocket / WebRTC / Hocuspocus),然后把它们传入。
附加
import * as Y from "yjs";
import { WebsocketProvider } from "y-websocket";
const ydoc = new Y.Doc();
const provider = new WebsocketProvider("wss://collab.example.com", docId, ydoc);
editor.collab.attach({
doc: ydoc,
provider: provider,
user: { id: "alice", name: "Alice", color: "#2563eb" },
textSync: "crdt", // per-node Yjs CRDT; load crdt-engine.min.js first
requireCrdt: true // do not silently fall back to legacy snapshots
});textSync: "crdt"。按节点的绑定会把可编辑 DOM 镜像到一个 Y.XmlFragment 中,保留并发的文本和格式更改,而无需旧方式那样重置整个正文。附加之后调用 editor.collab.getStatus(),可以记录当前生效的模式以及任何回退原因。
生产环境的 WebSocket 边缘服务
附带的协作服务器支持签名的、按房间限定的令牌、持久化的 LevelDB 状态、浏览器源允许列表,以及每个房间的连接数上限。在生产环境中请同时使用这四项控制;在代理上终止 TLS,不要暴露开放的 WebSocket 端点。
RTE_COLLAB_SECRET="use-a-long-random-secret"
RTE_COLLAB_PERSIST="/var/lib/rte-collab"
RTE_COLLAB_ALLOWED_ORIGINS="https://app.example.com,https://admin.example.com"
RTE_COLLAB_MAX_CONNECTIONS_PER_ROOM="100"
RTE_COLLAB_REDIS_URL="redis://redis:6379"
node server.js云端令牌端点会先验证文档所有权,然后再为某个房间签发短期凭据。服务器会以 HTTP 403 拒绝缺失或不在允许列表中的浏览器源,并以 HTTP 429 拒绝某个热门房间中超出上限的对等端。在每个副本上设置相同的 Redis URL,即可在不使用粘性会话的情况下转发文档和感知更新;加入活动房间的副本会先请求一份完整的 CRDT 状态快照,再同步它的第一个客户端。如果已配置的 Redis 不可用,/healthz 会返回 HTTP 503 和 status: "degraded"。重新连接之后,就绪状态会保持降级,直到一次内部 Pub/Sub 往返证明订阅已重新开始接收消息。
每个对等端都是不可信的输入
CRDT 通过直接把节点写入实时文档来应用远程编辑。它不经过粘贴处理或 setHTMLCode,因此只过滤这两个入口的编辑器,会在其他每位参与者的浏览器中执行某个协作者的 <iframe srcdoc>,并继续把它复制出去。请像对待粘贴的 HTML 一样对待共享文档上的合著者。
sanitizer.js 封堵了这条路径:它监视可编辑区域中插入的节点和属性,在任何可执行内容运行之前将其过滤,无论它来自哪里。普通输入没有任何开销,因为文本节点会被跳过,只有出现危险内容时过滤器才会介入。如果您的同步层已经在上游进行了净化,可以用 sanitizerGuardLiveDom: false 禁用它。您可以在在线验证页面上亲自运行这项检查。
发布测试套件会针对一个隔离的、真实的 Redis 兼容进程启动两个独立的 WebSocket 服务器进程,并验证延迟加入、双向的内容和在线状态、房间/令牌隔离、后端丢失、就绪状态恢复以及恢复后的第一次编辑。这是由厂商自行运行的集成测试证据,而不是托管服务的 SLA 或外部可靠性认证。
共享审阅台账
AI 建议、人工修订建议和批注都汇集到同一个存储中:editor.reviewLedger。正因为如此,审阅抽屉才能把它们交错显示,并且无论来源如何,接受/拒绝的方式都相同。
API
editor.reviewLedger.add(entry); // { id, changeType, author, text, replies[], ... }
editor.reviewLedger.update(id, patch);
editor.reviewLedger.remove(id);
editor.reviewLedger.get(id);
editor.reviewLedger.list();
editor.reviewLedger.refreshPanel();
分线程批注
批注锚定到选区范围,显示为高亮加侧边栏线程。包括撰写、回复、解决和删除。
配置
API