v0.1首个版本化设计基线查看版本范围
Developer

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。

能力声明

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

文本和图像、读和写都是独立能力;声明写入不获得读取。

Reference

用户取消、剪贴板没有相应类型或当前内容为空时返回 null,不抛异常。

图像示例

const buffer = new Uint8Array(16 * 1024 * 1024);
const image = await host.clipboard.readImage(buffer);
if (image) {
  const bytes = buffer.subarray(0, image.written);
  editor.insertImage(bytes, image.mime);
}

如果返回 required 大于 sink,应用可以在预算范围内重新分配并再执行一次用户已授权的读取;宿主不能把第二次调用变成无限期的后台读取授权。

写入图像:

const png = encodeSelectionAsPng();
await host.clipboard.writeImage(png, 'image/png');

原生 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。
  • 页面隐藏或焦点丢失时调用必须失败为 activation-required

格式与校验

v0.1 文本是有长度上限的 Unicode 字符串。图像只接受封闭的静态栅格 MIME 白名单;宿主根据魔数和完整解码重新判断类型,不能信任 guest 或系统剪贴板自报的 MIME。

安全与预算

  • 预算覆盖文本长度、图像压缩字节、解码像素、调用速率和解码内存。
  • SVG、HTML、脚本、动画图和包含外部引用的格式不在白名单。
  • 写入内容不得被平台偷偷附加追踪标识。
  • 读取结果不得进入宿主日志、遥测或错误详情。
  • 系统剪贴板变化本身不触发 guest 事件。

错误与测试

特有错误包括 activation-requireddeniedunsupported-formatsink-too-smallinvalid-datalimit-exceeded。一致性测试至少覆盖空剪贴板、取消、失焦、超长文本、伪造 MIME、解码炸弹、部分 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事件ime API输入ime.openSession()方法ime.updateState()方法ime.updateGeometry()方法ime.closeSession()方法ime.textUpdate event事件ime.composition event事件ime.formatUpdate event事件ime.characterBoundsRequest 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()方法clipboard.readImage()方法clipboard.writeImage()方法net API网络net.fetch()方法identity API身份identity.status()方法identity.login()方法identity.logout()方法env API平台集成env.snapshot()方法env.change event事件print API平台集成print.open()方法开始调用 Host API指南构建交互式绘图应用指南构建自绘文本编辑器指南管理媒体采集与播放指南组织本地数据与同步指南