构建自绘文本编辑器
自绘编辑器不能只监听键盘。按键控制用 input,真正文本合成用 ime,复制粘贴用 clipboard,持久化由 store 完成。
1. 聚焦并打开 IME
await host.input.focus('editor');
const ime = await host.ime.openSession('editor', {
text: document.text,
selection: document.selection,
inputMode: 'text',
multiline: true,
});
2. 应用编辑操作
host.events.on('ime.textUpdate', async ({ update, baseRevision }) => {
if (baseRevision !== document.revision) return;
document.replace(update.range, update.text);
await host.ime.updateState(ime, document.snapshot());
scheduleSave();
});
文档模型在 guest 中是权威状态。IME 事件是编辑请求,应用后再回传新 revision。
3. 同步几何
await host.ime.updateGeometry(ime, {
revision: document.revision,
editorBounds: layout.editor,
caretBounds: layout.caret,
});
在选择、滚动、字体或 canvas 尺寸变化后更新,不要无变化地逐帧发送。
4. 复制与粘贴
async function copy() {
await host.clipboard.writeText(document.selectedText());
}
async function paste() {
const text = await host.clipboard.readText();
if (text !== null) document.replaceSelection(text);
}
两个函数都要从可信用户操作直接进入。一次授权不得转成后台剪贴板读取。
5. 持久化
const previous = await host.store.get('documents/current');
await host.store.put(
'documents/current',
encodeDocument(document),
previous?.version,
);
处理 conflict,不要静默覆盖另一窗口的更新。
6. 关闭
await host.ime.closeSession(ime);
失焦、文档关闭和视图销毁都要清理会话。