ebox/docs/user/ebox-api-reference.zh.md

15 KiB
Raw Blame History

Ebox 公共 API 参考

English

本文描述独立 Ebox 包当前的公共边界,并把普通 author 路径与框架集成使用的 evaluated typed API 分开。以 ebox-- 开头的名称都是私有实现。

Ebox 需要 Emacs 29.1 或更高版本、ECSS 和 TP

(require 'ebox)

1. Author 语法

ebox-build 只接受以下 author 入口:

STRING
(text PROPERTY VALUE ... STRING)
(box PROPERTY VALUE ... CHILD ...)
(row PROPERTY VALUE ... CHILD ...)
(column PROPERTY VALUE ... CHILD ...)
(flex PROPERTY VALUE ... CHILD ...)
(grid PROPERTY VALUE ... CHILD ...)

STRING(text STRING) 的简写。Text form 必须且只能有一个字符串 payload。 每种 Box form 都接受零个或多个直接嵌套的 Text/Box 子节点。form 名称选择 Normal、 Row、Column、Flex 或 Grid 子布局author 不通过 property 传入布局选择器。

ebox-build 返回一个不透明的 CanonicalEboxInput,以原子整体携带有序 canonical forest 和拥有其 author facts 的 source generation。普通 author 代码只把这个值原样 传给 Ebox 渲染/发布函数,不取出 node也不构造 source index。

(ebox-build
 '(column :padding (1 2)
          (box :id "status" :color "#166534" "Ready")
          (row :item-gap 1
               (box "Left")
               (box "Right"))))

author source field 是 :key:class:id:outer 可取 inlineblock,控制 Box 如何参与父布局。

布局拥有的 property

Form 或关系 Property
rowcolumn :item-gap:cross-align
flex :flex-direction:flex-wrap:flex-flow:justify-content:align-items:align-content:gap:row-gap:column-gap
flex 的直接子 Box :order:flex:flex-grow:flex-shrink:flex-basis:align-self
grid :grid-template-columns:grid-template-rows:grid-auto-columns:grid-auto-rows:grid-auto-flow:justify-items:justify-content:align-items:align-content:gap:row-gap:column-gap
grid 的直接子 Box :order:grid-column:grid-row:grid-column-span:grid-row-span:align-self

participation property 就是普通子 Box property不会创建另一种公共节点或 wrapper。

当前常用 property

范围 当前输入
尺寸 :box-sizing:width:min-width:max-width:height:min-height:max-height
边缘 :padding:margin:border、各 side shorthand 与 longhand
绘制 :color:background-color、精确 alias :bgcolor、border color、:visibility
文本布局 :text-align:wrap-modewordcharkpnone
Overflow :overflowvisiblehiddenscroll

普通横向数字表示字符列,单元素横向 list 表示像素纵向数字表示行数。Border width 是例外,始终使用非负整数像素,因此写 (1 solid "#687386"),不写 ((1) solid "#687386")(viewport)(viewport-height) 使用当前 render context。property 验证属于 Eboxcontext/value 组合无效时会直接报错。

2. Evaluated typed construction

已经拥有 author parsing 的框架可以使用 evaluated 集成 API它不是第二套 author 语法。一个 ebox-source-builder 拥有完整 source generation每个 typed node 都携带 该 builder 返回的 handle以及由同一份 normalized declarations 投影出的 node-owned facts。最后用一个 CanonicalEboxInput 同时传递 forest 与封存的 source index

(let* ((builder (ebox-source-builder-create))
       (root-declarations nil)
       (left-declarations nil)
       (right-declarations nil)
       (root-handle
        (ebox-source-builder-bind
         builder :declarations root-declarations))
       (left-handle
        (ebox-source-builder-bind
         builder :declarations left-declarations))
       (right-handle
        (ebox-source-builder-bind
         builder :declarations right-declarations))
       (left
        (ebox-text-create
         :value "Left"
         :source-handle left-handle
         :owned-facts
         (ebox-canonical-facts-from-declarations
          'text left-declarations)))
       (right
        (ebox-text-create
         :value "Right"
         :source-handle right-handle
         :owned-facts
         (ebox-canonical-facts-from-declarations
          'text right-declarations)))
       (root
        (ebox-box-create
         :layout (ebox-row-layout-create
                  :item-gap 1 :cross-align 'center)
         :children (list left right)
         :source-handle root-handle
         :owned-facts
         (ebox-canonical-facts-from-declarations
          'row root-declarations))))
  (ebox-canonical-input-create
   (list root)
   (ebox-source-builder-finish builder)))
  • ebox-source-builder-create 开始且只开始一次 mutable source assembly
  • ebox-source-builder-bind 保存 normalized source facts并返回只含 identity 的 opaque handle
  • ebox-source-builder-finish 分离并封存 builder 的 immutable fact index封存后 builder 拒绝继续修改;
  • ebox-canonical-facts-from-declarations 从传给 source builder 的同一份 normalized declarations 投影 node-owned facts
  • ebox-text-create 要求 :value:source-handle:owned-facts
  • ebox-normal-layout-create 构造 Normal LayoutConfig
  • ebox-row-layout-createebox-column-layout-create 接受 :item-gap:cross-align
  • ebox-flex-layout-create 构造经过验证的 Flex LayoutConfig
  • ebox-grid-layout-create 构造经过验证的 Grid LayoutConfig
  • ebox-box-create 要求 :layout:source-handle:owned-facts,并接受 typed node 的 :children list
  • ebox-canonical-input-create 把有序 node forest 与拥有其中全部 handle 的唯一 source index 组合为一个值;这个边界验证精确 handle 集合,并从 forest 的最终 preorder 封存 source order不依赖 bottom-up 构造顺序。
  • ebox-canonical-input-root-host-ref 返回经过验证的 single-root input 的分离发布 地址,不暴露其中的 source handle
  • ebox-canonical-input-roots 返回 exact top-level roots 的 shallow、只读副本 不会把 source facts 导入另一个 candidate
  • ebox-canonical-input-import-roots 只接受该 input 中 exact、唯一的 top-level roots 与一个 open source builder它只导入选中 subtree 的 facts保留 node、 source-handle 与 immutable record identity绝不接管未选 root 的 facts
  • ebox-canonical-input-equal-p 比较完整 canonical forest、Range anchor、source identity 和 immutable source facts用于 no-op 证明。

这些 source builder、fact/input constructor 与 typed node/layout constructor 只属于 evaluated 集成契约;其中的 field 不是 author property也不是另一套 DSL。

typed 模块还公开 ebox-node-kindebox-text-node-pebox-box-node-pebox-node-source-handleebox-text-node-valueebox-box-node-layoutebox-box-node-childrenebox-box-node-range-anchors。下面的 facade 清单重点列出 应用入口,因此不重复这些 inspection function。

3. 渲染与 retained 发布

函数 契约
ebox-render 接收 single-root CanonicalEboxInput,返回带属性字符串,不发布 live buffer。
ebox-render-to-buffer 接收 single-root CanonicalEboxInput,挂载 retained TP surface启用 ebox-buffer-mode 并返回 buffer可选 plist 只接受 :observer FUNCTION
ebox-display-buffer 接收 single-root CanonicalEboxInput,走 retained 路径渲染,删除其他 window 后切换到结果。
ebox-commit 原子发布 single-root CanonicalEboxInputebox-candidate-begin 返回的 one-shot logical candidate。
ebox-buffer-set-observer 给已经 mounted 的 buffer 设置或移除一个 function observer。
ebox-buffer-update-report 返回最近一次成功更新报告的防御性副本。
ebox-rerender-buffer-with-context 应用显式 viewport width 与可选 height同时保留 identity。
ebox-viewport-window-width 返回 Ebox 对 window 使用的 display-safe 像素宽度。

ebox-commit 接受可选 framework publish/rollback callback。它们加入现有原子发布 失败会恢复旧 buffer、surface、runtime state 与最近一次成功报告。

每个公共 Ebox publication 都拥有自己的 TP transaction。在已经 active 的外层 TP transaction 中调用 mount、commit、viewport、region、selector、batch 或 TP-backed scroll publication会在 Ebox mutation 前被拒绝。

观察是可选只读边界,不拥有 transaction 权限。observer 签名是 (OBSERVER BUFFER REPORT)。一次 TP publication 被接受且 Ebox finalization 全部完成后, observer 按顺序收到两份防御性 flat report先 TP后 Ebox。两者共享从 TP transaction id 得到的 :correlation-id。Ebox stage 是 mountcommitviewportregionselectorbatchscroll。嵌套公共调用复用最外层 operation 因此多匹配 selector 或显式 batch 仍只发送一对 report。没有 TP surface publication 的 no-op 与 native-window scroll 不发送 report。observer error 在 accept 后被包含, 不能回滚渲染。

需要观察首次 mount 时,把 :observer 传给 ebox-render-to-buffer。mount report 只 瞬时发送;有无 observer 时 ebox-buffer-update-report 都仍为 nil。后续通过 ebox-buffer-set-observer 替换 observer传 nil 时移除并从 TP surface 解绑 bridge。 observer 为 nil 时Ebox 不创建 observation context不取 timestamp/GC snapshot 也不装饰 report。

ebox-call-with-render-burst 是框架 callback 的 exception-safe allocation/GC 边界。 ebox-render-burst-beginebox-render-burst-end 提供较底层的 token 形式,必须用 unwind-protect 配对。它们本身不发布内容。

4. Identity、直接更新与 logical candidate

函数 契约
ebox-region-ids 按文档顺序返回当前底层 region id。
ebox-region-resolve 把 mounted buffer 中一个逻辑 :id 解析为不透明、surface-scoped 的 handle。
ebox-region-update 通过一次 retained transaction 应用支持的可变样式或滚动 property。
ebox-child-range 仅供框架集成:在组装 typed canonical input 时构造非视觉、可寻址的 child Range descriptor。
ebox-candidate-begin 在 one-shot candidate 中捕获当前准确 mounted generation。
ebox-candidate-replace 用 single-root CanonicalEboxInput 替换一个 candidate node address。
ebox-candidate-replace-range-ref 用 forest-valued CanonicalEboxInput 替换一个透明 child Range payload。
ebox-candidate-replace-root 用 single-root CanonicalEboxInput 替换 candidate 的私有 root address。
ebox-candidate-replace-host-ref 用 single-root CanonicalEboxInput 替换一个 framework-owned opaque host reference。
ebox-candidate-patch-host-paint 比较 previous/next single-root canonical input记录经过证明的 paint-only host patch需要 replacement 时返回 nil。
ebox-host-ref-bounds 返回 opaque host reference 当前不含 margin 的 bounds。
ebox-host-ref-position 返回其当前第一个位置。

handle 和位置只属于一个 live publication generation对象被删除后要重新解析。 candidate 被 commit 封存后不能复用。

author DSL 没有 Range form。普通 author 只组合直接嵌套的 Text/Box child不调用 ebox-child-rangeRange address 只服务已经拥有 semantic child range 与 candidate update 的框架。

5. Selector

ECSS 是唯一 selector parser 与 matcherEbox 只提供 logical tree relation 和 mounted index。

函数 契约
ebox-selector-parse 把 CSS-like selector 编译为 ECSS AST。
ebox-selector-match-node-p 用 selector 或 AST 匹配一个 built node。
ebox-selector-query-all 按文档顺序查询 unmounted built tree。
ebox-selector-query-buffer 查询一个 mounted runtime。
ebox-selector-update-buffer 更新所有可编辑 mounted match 并返回结构化报告。
ebox-select-all ebox-selector-query-buffer 的 alias。
ebox-update-selector ebox-selector-update-buffer 的 alias。

6. 滚动

ebox-buffer-mode 安装 ebox-scroll-map。map 会把行、页和滚轮意图先交给最内层 semantic scroll owner再回退到普通 Emacs 滚动。

公共命令是 ebox-scroll-downebox-scroll-upebox-scroll-page-downebox-scroll-page-upebox-wheel-scroll-downebox-wheel-scroll-upebox-scroll-state 根据数字 region id 返回只读快照。

7. 测量、缓存与构建工具

函数 契约
ebox-string-pixel-width 测量字符串第一行的 display width。
ebox-display-signature 返回 measurement cache invalidation 使用的 display 输入。
ebox-clear-cache 清理 Ebox measurement/render cache。
ebox-byte-compile 编译 Ebox 活跃 Elisp 源码;重启 Emacs 后加载新 bytecode。
ebox-native-status 报告 native toolchain、module、ABI 与加载状态。
ebox-native-build 异步构建并安装可选 native 模块。

native 模块只是加速器,不是正确性依赖。加载包不会构建它。

8. Facade 清单

ebox-public-api 保存稳定 facade 入口。下面的分组列出其中每一个名称:

  • 构造:ebox-buildebox-text-createebox-normal-layout-createebox-row-layout-createebox-column-layout-createebox-flex-layout-createebox-grid-layout-createebox-box-create
  • 渲染/发布:ebox-renderebox-render-to-bufferebox-display-bufferebox-commitebox-buffer-set-observerebox-buffer-update-reportebox-rerender-buffer-with-contextebox-viewport-window-widthebox-call-with-render-burstebox-render-burst-beginebox-render-burst-end
  • Candidate/identityebox-candidate-beginebox-candidate-replaceebox-candidate-replace-range-refebox-candidate-replace-rootebox-candidate-replace-host-refebox-candidate-patch-host-paintebox-child-rangeebox-region-idsebox-region-resolveebox-region-updateebox-host-ref-boundsebox-host-ref-position
  • Selectorebox-selector-parseebox-selector-match-node-pebox-selector-query-allebox-selector-query-bufferebox-selector-update-bufferebox-select-allebox-update-selector
  • 滚动:ebox-buffer-modeebox-scroll-mapebox-scroll-downebox-scroll-upebox-scroll-page-downebox-scroll-page-upebox-wheel-scroll-downebox-wheel-scroll-upebox-scroll-state
  • 测量/构建:ebox-string-pixel-widthebox-display-signatureebox-clear-cacheebox-byte-compileebox-native-statusebox-native-build

9. 验证

make load EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make compile EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make docs-contract-tests EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make dsl-tests EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
make check EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs