ecss/docs/architecture.zh.md

4.6 KiB
Raw Blame History

ecss 架构

English

定位

ecss 是“规则如何赢、最终属性值是什么”的通用纯计算层。它把 consumer 提供的 property schemas、subjects、stylesheets、inline declarations 与 parent computed style 转换成 computed values、custom properties、active properties、specified properties、provenance 和 diagnostics。

consumer schemas + subject adapter + stylesheet + parent style
                              │
                              ▼
       selector match → candidate collection → cascade winner
                              │
                              ▼
        CSS-wide/custom-property resolution → normalize/validate
                              │
                              ▼
    computed style + specified properties + provenance + diagnostics

ecss 不知道 computed values 最终如何显示。TP 可以把最终文本属性贡献转换成 retained surface patchEbox 可以把最终 Box/Flex/Grid 属性解释成 measurement、layout 与 painting 后果;普通调用者也可以完全不用 TP/Ebox。

Package schema 与显式 surface

每个 owning package 一次创建不可变 ecss-schema-package;具体 surface 再用 ecss-schema-set-compose 原子组合所需 package。组合阶段统一拒绝重复 package、canonical/canonical、canonical/alias 与 alias/alias 冲突,不存在进程全局 mutable registry 或 last-wins 注册。两个应用因此可以在同一 Emacs 中组合不同 property vocabulary 而互不污染。

Alias 只属于声明归一化入口,进入 cascade 前消失;同一声明中 alias/canonical 重复或 shorthand 与其输出 longhand 冲突会立即失败。Schema set 同时保存 owner、impact 与 projection factscomputed style 直接引用该 set不建立第二棵 computed tree。Package/schema set 不提供 mutator公共查询返回 detached 数据。

Stylesheet 仍是每个调用者显式拥有的可变 authoring 对象。同一 stylesheet 中的 UA、user 与 author origin 分别维护 layer orderrule 添加是原子的,一次失败不会留下半添加 layer 或错误 source order。

Subject 与 adapter

简单场景直接使用 ecss-subject。已有树模型通过 ecss-subject-adapter-create 提供 type、id、classes、attributes、states、parent 与 children callback不需要把业务节点复制成 ECSS node。selector query 与 stylesheet 都调用同一个 parser、matcher 和 specificity 实现,因此不会出现“查询能匹配但样式规则不能匹配”的两套语义。

Cascade 顺序

候选值按 CSS 顺序比较relevance/match、origin+importance、cascade layer、specificity、scope proximity、source order、declaration order。标准 origin level 是 UA normal、user normal、author normal、animation、author important、user important、UA important、transition。normal layer 后声明者优先且 unlayered 高于 layeredimportant layer 反向inline author declaration 在 author origin 内保持最高优先级。

revert 删除当前整个 origin 后重新选择,不区分 normal 与 importantrevert-layer 删除当前 origin 中的整个 layer 后重新选择。invalid-at-computed-value 不会退回较低候选,而是使用 inherited/initial fallback并在 provenance 中记录 invalid winner。

Value source 边界

ECSS 不自动调用属性里的 function也不定义自己的 reactive/computed wrapper。调用者需要求值时显式向 ecss-compute-style 传入 :value-resolver。resolver 接收 value、property、subjectECSS 对每个被选中的 source 只调用一次resolver 返回值不会被二次执行。resolver error 直接向外传播;由于 computation 是纯计算,不存在需要 ECSS 回滚的 Buffer 或 runtime state。

Custom properties

Custom properties 使用 --name symbol通过普通 cascade 选出 raw value默认从 parent computed style 继承,再用 ecss-var 解析。引用可以嵌套在 list/vector 中;缺失值与 cycle 可使用引用处 fallback。cycle 不破坏整个 computed style而产生 deterministic diagnostic并把受影响 value 标记为 invalid-at-computed-value。

三包边界

ecss: selector / stylesheet / cascade / computed values
tp:   text-property contributions / reactive runtime / diff / transaction / buffer commit
ebox: box semantics / measurement / flex-grid layout / painting / dirty ownership

允许的依赖方向是 Ebox 消费 ecss 与 TPecss 和 TP 可以彼此完全独立使用。ecss public API 不出现 TP object/binding/mount、Ebox node、marker、patch 或 buffer mutation。