v0.1首个正式支持的版本化规范查看版本范围

clipboard

clipboard 在可信用户操作中读写系统剪贴板。读操作把其他应用或系统中的内容带入 guest;写操作把 guest 已有内容交给用户可见的系统剪贴板,两者分别授权和定档。

基本示例

async function pasteIntoEditor() {
  const text = await host.clipboard.readText();
  if (text !== null) editor.insert(text);
}

async function copySelection() {
  await host.clipboard.writeText(editor.selectedText());
}

两个函数都必须直接由点击、快捷键等可信用户操作触发。

适用场景

  • 文本编辑器的复制与粘贴。
  • 用户主动把应用结果交给另一个应用。

剪贴板图像、历史、后台监听、自定义私有格式、HTML、文件列表和无交互轮询不在 v0.1。

L1 边界

宿主独占的是系统剪贴板与当前可信用户操作。guest 无法自行读取或写入其他应用共享的剪贴板;文本编辑命令、格式转换和剪贴板历史都可在 guest 中实现,不进入 L1。

能力声明

{
  "capabilities": [
    "host:clipboard.readText",
    "host:clipboard.writeText"
  ]
}

读和写是独立能力;声明写入不获得读取。

Reference

用户取消或剪贴板没有纯文本类型时返回 null,不抛异常;存在的空文本返回空字符串,不能与 null 混同。两种方法都接受末尾 CallOptions;取消与剪贴板读取/写入提交点线性排序,取消先发生则以 cancelled 失败且不读写,提交先发生则返回正常结果,后到的取消不改写结果。

原生 WASM 示例

char text[MAX_PASTE_BYTES];
ClipboardTextResult r = host_clipboard_read_text(utf8_sink(text, sizeof(text)));
if (r.present) editor_insert_utf8(text, r.written);

宿主必须验证 UTF-8 并明确返回实际写入长度,不能依赖 NUL 终止。

授权与生命周期

  • 每次方法调用都必须继承当前可信用户操作。
  • 用户的一次点击只授权当前调用,不产生可持久化剪贴板句柄。
  • 读操作的 provenance 为 external-resource,信任档位为 lime。
  • 写操作固定为 green;符合 v0.1 的宿主必须同时执行长度/速率预算、纯文本形状校验和逐次审计,否则不支持该方法。
  • 页面隐藏或焦点丢失时调用必须失败为 activation-required

格式与校验

v0.1 只接受有 UTF-8 字节上限的纯 Unicode 文本。NUL 是普通字符;宿主不得把文本解释为 HTML、URL 或命令,也不得正规化 Unicode、改写换行或更改任何标量值。绑定必须明确实际长度,不能依赖 NUL 终止。

安全与预算

  • v0.1 预算键为 clipboard.maxTextBytesclipboard.readsPerMinuteclipboard.writesPerMinute
  • 写入内容不得被平台偷偷附加追踪标识。
  • 读取结果不得进入宿主日志、遥测或错误详情。
  • 系统剪贴板变化本身不触发 guest 事件。

错误与测试

特有错误包括 activation-requireddeniedcancelledsink-too-smallinvalid-datalimit-exceeded。一致性测试至少覆盖空剪贴板、用户取消与调用取消的区分、提交竞态、失焦、超长文本、NUL、无效 Unicode、原生 sink、读写权限分离和调用预算。

Host API 版本与分层概览Host API v0.1版本非正式提议提议canvas API呈现canvas.getInfo()方法canvas.draw()方法canvas.present()方法canvas.measureText()方法canvas.frame event事件canvas.resize event事件asset API呈现asset.read()方法asset.loadFont()方法playback API呈现playback.open()方法playback.write()方法playback.stop()方法playback.ready event事件playback.ended event事件input API输入input.focus()方法input.pointer event事件input.key event事件input.wheel event事件input.focusChange event事件ime API输入ime.openSession()方法ime.updateState()方法ime.updateGeometry()方法ime.closeSession()方法ime.textUpdate event事件ime.composition event事件ime.formatUpdate event事件ime.characterBoundsRequest event事件ime.ended event事件capture API输入capture.requestCamera()方法capture.requestMic()方法capture.frame()方法capture.readAudio()方法capture.stop()方法capture.ended event事件store API数据store.get()方法store.put()方法store.delete()方法store.list()方法store.deletePrefix()方法clipboard API数据clipboard.readText()方法clipboard.writeText()方法env API平台集成env.snapshot()方法env.change event事件开始调用 Host API指南构建交互式绘图应用指南构建自绘文本编辑器指南管理媒体采集与播放指南组织本地数据与同步指南