跳到主要内容

arc#6715 · 尚未发布 ARC tag

收藏与笔记(save 能力)

在 blocklet.yaml 的 save: 上声明页面收藏和划词笔记。默认开启,未登录不出现,侧栏或页面按钮。

页面收藏和划词笔记是 blocklet 级能力。省略 save: 即开启。Chrome 在访客通过身份验证之前不出现。这不是页面内评审(?review=1),不是评论,也不是 connect-service User Center。

本页证据是 Arc feat/save-capability 上的解析器与运行时(arc#6715PR #6716):packages/core/src/blocklet/save-capability.tsparse-manifest.tssave:packages/aup/src/save-surface.tspackages/aos/src/session/bookmark.tsannotate.ts。它不是已发布的 arc --version tag。不要把它当成旧 host 上已有的合同。

动机见:收藏是运行时能力,不是站点插件

如何声明

写在 blockletblocklet.yaml 上,不要写进 .web/site.yaml,也不要写在某一页。

输入规范化 { enabled, chrome }HTML data-arc-save-capability
省略 / null / true{ enabled: true, chrome: "floating" }floating
false{ enabled: false, chrome: "floating" }off
{ enabled: false }{ enabled: false, chrome: "floating" }off
{ chrome: "buttons" }{ enabled: true, chrome: "buttons" }buttons
{ enabled: true, chrome: "floating" }同左floating

yaml
# 默认:省略该字段

save: false

save:
  enabled: false

save:
  chrome: buttons

字段参考

类型默认说明
saveboolean 或对象省略 = 开blocklet.yaml 顶层。spec v1 与 v2。
save.enabledboolean除非值为恰好 false,否则 true只有 false 才关闭。对象里缺这个键仍开启。
save.chrome"floating" | "buttons""floating"规范化时其它字符串当 floating解析器拒绝未知枚举。
对象多余键拒绝(.strict())。save: { chrome: floating, extra: 1 } 解析失败。

布尔 save: true 可写,等于默认。

登录门闩

信号效果
save 关闭(data-arc-save-capability="off"无 chrome。页面上的 [data-arc-save] 保持隐藏(html:not([data-arc-save-ready]) [data-arc-save] { display: none })。
无 session 或 authenticated: falsechrome 与关闭相同。声明本身不变。
authenticated: true 且能力开启data-arc-save-ready 设为 floatingbuttons,并挂上对应模式。

未登录时,若仍点到收藏控件:点 header 的 Login,或跳 /login?redirect=<当前 path+query>

Web Device 通过 window.__arcSessionCtx / __arcSessionWaiters 发布 session。AUP 在 blocklet 设置了 save 时,在 render/stage 帧上带 msg.saveoff | floating | buttons)。客户端先把它写到 window.__arcSave 和 HTML 属性,再排空 waiter。

共享 IIFE 的覆盖顺序:window.__arcSave(字符串或 { enabled, chrome })优先于 HTML 属性。两者都缺 → floating

展示模式

floating(默认)

登录后出现侧栏(.arc-save-bardata-arc-save="bar"):

控件data-arc-save动作
Bookmarkbookmarkexec("/.actions/bookmark", { url, title })
My saveslibrary跳到 /{locale}/my/
划词(mouseup)选中文本长度 ≥ 2 时打开笔记框 → /.actions/annotate

urlwindow.location.hreftitle 在非空时用 document.title

My saves 的 locale:若 location.pathname 匹配 ^/([a-z]{2}(?:-[A-Za-z0-9]+)?)/,用 /{该段}/my/。否则 /my/

buttons

无侧栏。无自动划词弹层。绑定页面自己的控件:

data-arc-save本模式是否必需已登录时的行为
bookmark同上 bookmark exec;设置 aria-pressed
annotate可选打开笔记框(有选区就用选区)
library可选/{locale}/my/
bar仅运行时不当点击目标

html
<button type="button" data-arc-save="bookmark">Bookmark</button>
<button type="button" data-arc-save="annotate">Annotate</button>
<a data-arc-save="library">My saves</a>

点击向上冒泡:从 event target 往上走到第一个不是 bardata-arc-save

HTML 属性

属性位置取值谁写入
data-arc-save-capability<html>off | floating | buttonsWeb Device finalizePageHtml / stampSaveCapabilityHtml。AUP 在 msg.save 为这三者之一时由 handleAup 写入。
data-arc-save-ready<html>floating | buttons客户端,仅在已登录且能力开启后。关闭或匿名时移除。
data-arc-save控件bar | bookmark | annotate | library浮动栏(运行时)或页面作者(buttons 模式)。

盖章幂等:<html> 上已有 data-arc-save-capability 则不再改写。属性加在标签结束符之前,不打乱 lang / data-tone

Actions

两个 action 都写入本 session 调用者的 DID Space。线上传入的 path / target / collection 被忽略。Workbench 私有字段(tagIdsstatuscollectionIdsdataVersionversion)被拒绝。

/.actions/bookmark

参数必填说明
url绝对 http:https: URL。成为 objectId
title记录 name。无标题时从 URL 派生标签(最后一段 path 或 hostname)。标签不是出处。
ctype / contentType / schemaType只允许 ABOUT 类型:link(默认)、placeproduct。未知声称类型直接拒绝,不会改写成 link
notes / text / descriptionL1 记录上的可选正文。浮动栏不发送这些字段。

写入路径:/user/bookmarks/{id}id = b_ + SHA-256(url) 前 16 字节的 hex。

成功:{ ok: true, id, path, copied }。同一 URL 再存:copied: false(同一 id)。

error.code何时
unauthorizedcallerDid,或 /user 写入被拒 / 找不到
invalid-url缺省或不是绝对 http(s)
unknown-type声称类型不是 link / place / product
invalid-record内置 schema 校验失败
workbench-private-fieldpayload 仍带 Aside 私有字段

/.actions/annotate

参数必填说明
url绝对 http(s) 页面 URL → isBasedOn
quote除非有 text选中文本 → 记录 text
textquote 的别名quote 为空时使用
note可选;存为记录 name

写入路径:/user/notes/{id}id = n_ + SHA-256(url + "\n" + quote + "\n" + note) 前 16 字节 hex。contentType: note

error.code何时
unauthorized无 caller,或 /user 写入被拒
invalid-url缺省或不是绝对 http(s)
invalid-quotequotetext 都空
invalid-recordschema 校验失败
workbench-private-field带了 Aside 私有字段

浮动栏只在当前选区长度 ≥ 2 时打开笔记框。

/my/ 组合页

内置路由:/{locale}/my/(locale 规则与 My saves 相同)。不是 /.well-known/service/user

save 开启时,段落固定先是:

idlabelpath
bookmarksBookmarks/user/bookmarks
notesNotes/user/notes

然后是声明了 faces.my: true 并且活在 /user 下的 collection。重复的 idpath 跳过。composeMyPageSections 传入 { save: false } 时(运行时在 save.enabled 为 false 时这样做):内置书签/笔记段消失;额外的 faces.my 集合仍在。

失败与边界

边界行为
解析未知 save.chromeManifest 解析抛错(enum)
解析未知对象键Manifest 解析抛错(strict)
规范化垃圾值(数组、随意对象)运行时当默认开 / floating,除非 enabled: false
匿名访客无 chrome;[data-arc-save] 隐藏
save: false属性 off/my/ 去掉内置段
未登录调 actionunauthorized
非 http(s) urlinvalid-url
floating 模式下选区长度 0 或 1无弹层
跨站阅读列表不是这个能力。记录是这个站上该调用者的 /user/**
页面内评审另一套 overlay。见 页面内评审模式

相关页面