feat(tp): isolate stylesheet rule domains
Give independent consumers their own rules, cascade layer ordering, and source-order counters so packages such as Ebox cannot pollute TP's default stylesheet or each other. Match generic class and state tokens by value and document caller-owned stylesheet lifecycle. Verified: make clean; make test (728/728); make compile WERROR=t; checkdoc tp-style.el; git diff --check; Ebox make test against ../tp.
This commit is contained in:
parent
07b84b0685
commit
1195297011
@ -174,7 +174,7 @@
|
||||
|
||||
Since 0.2.0 the library is organized as a family of layered modules (`tp-core`, `tp-style`, `tp-reactive`, `tp-layer`, `tp-ops`, `tp-search`, `tp-render`, `tp-stack`, `tp-query`, `tp-palette`, `tp-builtins`) behind the umbrella file `tp.el` — `(require 'tp)` still loads everything, so nothing changes for users. See [Installation](#installation) for the module map.
|
||||
|
||||
The TP 1.0 migration has begun with a pure schema-driven cascade kernel. `tp-style.el` adds namespaced property schemas, structured selectors, origin/importance/layer/specificity/scope/source-order precedence, property-specific inheritance, tagged CSS-wide values, inherited custom properties, explicit `tp-computed` sources, projection to Emacs properties, and read-only winner provenance. It deliberately owns no buffers, markers, mounts, or reactive subscriptions; retained surfaces will build on this kernel in later migration phases.
|
||||
The TP 1.0 migration has begun with a pure schema-driven cascade kernel. `tp-style.el` adds namespaced property schemas, structured selectors, origin/importance/layer/specificity/scope/source-order precedence, property-specific inheritance, tagged CSS-wide values, inherited custom properties, explicit `tp-computed` sources, projection to Emacs properties, and read-only winner provenance. `tp-stylesheet-create` gives each independent consumer its own rule, layer, and source-order domain instead of forcing unrelated packages through one process-global stylesheet. It deliberately owns no buffers, markers, mounts, or reactive subscriptions; retained surfaces will build on this kernel in later migration phases.
|
||||
|
||||
`tp-reactive.el` now also provides the TP 1.0 exact dependency runtime: signals invalidate only their subscribed bindings, binding reads form memoized binding→binding edges, conditional computations replace obsolete dependencies, and the outermost `tp-with-transaction` flushes each dirty binding once. Candidate signal writes and binding values/dependencies commit together; compute, cycle, publication, or transaction-participant failures roll them back. `tp-transaction-participate` lets a client promote opaque side state after surfaces publish while supplying its inverse for the same rollback boundary. Global and buffer-local variable adapters reuse this graph without making text properties or buffer scans the runtime database.
|
||||
|
||||
@ -516,11 +516,11 @@ A complete overview of all tp.el functions organized by category:
|
||||
| `tp-subject-create` / `tp-subject-set-children` | Build consumer-independent selector subjects and relations |
|
||||
| `tp-selector-match-p` / `tp-selector-specificity` | Match the structured selector AST and compute its specificity |
|
||||
| `tp-define-style` / `tp-style-declarations` / `tp-undefine-style` | Register, inspect, and remove defensive named declarations |
|
||||
| `tp-stylesheet-add-rule` | Add an origin/layer/scope-aware structured rule |
|
||||
| `tp-stylesheet-create` / `tp-stylesheet-add-rule` | Create an isolated rule/layer domain and add origin/layer/scope-aware structured rules |
|
||||
| `tp-wide-value` / `tp-important` / `tp-var` | Construct unambiguous cascade values without reserving ordinary Elisp symbols |
|
||||
| `tp-computed` | Mark the only function values TP should execute |
|
||||
| `tp-compute-style` / `tp-project-style` | Compute canonical values/provenance and project final Emacs text properties |
|
||||
| `tp-style-reset-rules` / `tp-style-reset` | Reset stylesheet-only state or the complete style registry |
|
||||
| `tp-style-reset-rules` / `tp-style-reset` | Reset one isolated/default stylesheet, or TP's global schemas, named styles, and default stylesheet |
|
||||
|
||||
#### Signals and Bindings
|
||||
|
||||
|
||||
@ -173,7 +173,7 @@
|
||||
|
||||
自 0.2.0 起,本库被组织为一组分层模块(`tp-core`、`tp-style`、`tp-reactive`、`tp-layer`、`tp-ops`、`tp-search`、`tp-render`、`tp-stack`、`tp-query`、`tp-palette`、`tp-builtins`),由伞形文件 `tp.el` 统一加载 — `(require 'tp)` 仍会加载全部模块,对用户没有任何变化。模块一览见[安装](#安装)。
|
||||
|
||||
TP 1.0 迁移已经从纯 schema-driven cascade kernel 开始。`tp-style.el` 新增 namespaced property schema、结构化 selector、origin/importance/layer/specificity/scope/source-order 优先级、逐属性继承、带 tag 的 CSS-wide 值、可继承 custom property、显式 `tp-computed` source、Emacs 属性投影和只读 winner provenance。这个模块刻意不拥有 buffer、marker、mount 或响应式订阅;后续 retained surface 会建立在同一个 kernel 上。
|
||||
TP 1.0 迁移已经从纯 schema-driven cascade kernel 开始。`tp-style.el` 新增 namespaced property schema、结构化 selector、origin/importance/layer/specificity/scope/source-order 优先级、逐属性继承、带 tag 的 CSS-wide 值、可继承 custom property、显式 `tp-computed` source、Emacs 属性投影和只读 winner provenance。`tp-stylesheet-create` 让每个独立 consumer 拥有自己的 rule、layer 与 source-order domain,不必让无关包共享一份进程全局 stylesheet。这个模块刻意不拥有 buffer、marker、mount 或响应式订阅;后续 retained surface 会建立在同一个 kernel 上。
|
||||
|
||||
`tp-reactive.el` 现在也提供 TP 1.0 的精确依赖 runtime:signal 只 invalidates 真实订阅的 binding,binding read 建立 memoized binding→binding edge,条件计算会替换已经失效的旧依赖,最外层 `tp-with-transaction` 对每个 dirty binding 最多 flush 一次。candidate signal write 与 binding value/dependencies 一起提交;compute、cycle、publication 或 transaction participant 失败时一起回滚。`tp-transaction-participate` 允许 client 在 surface 发布后晋升 opaque side state,同时为同一 rollback boundary 提供逆操作。global 和 buffer-local variable adapter 复用同一 graph,不再把文本属性或 buffer scan 当作新 runtime database。
|
||||
|
||||
@ -511,11 +511,11 @@ tp.el 所有函数按类别组织的完整概览:
|
||||
| `tp-subject-create` / `tp-subject-set-children` | 构造与具体 consumer 无关的 selector subject 和关系 |
|
||||
| `tp-selector-match-p` / `tp-selector-specificity` | 匹配结构化 selector AST 并计算 specificity |
|
||||
| `tp-define-style` / `tp-style-declarations` / `tp-undefine-style` | 注册、查询并移除防御性复制的 named declarations |
|
||||
| `tp-stylesheet-add-rule` | 添加支持 origin/layer/scope 的结构化 rule |
|
||||
| `tp-stylesheet-create` / `tp-stylesheet-add-rule` | 创建隔离的 rule/layer domain,并添加支持 origin/layer/scope 的结构化 rule |
|
||||
| `tp-wide-value` / `tp-important` / `tp-var` | 构造无歧义 cascade 值,不占用普通 Elisp symbol |
|
||||
| `tp-computed` | 标记 TP 唯一应该执行的 function value |
|
||||
| `tp-compute-style` / `tp-project-style` | 计算 canonical values/provenance 并投影最终 Emacs text properties |
|
||||
| `tp-style-reset-rules` / `tp-style-reset` | 仅重置 stylesheet state,或重置完整 style registry |
|
||||
| `tp-style-reset-rules` / `tp-style-reset` | 重置某个隔离/default stylesheet,或重置 TP 的全局 schema、named style 与 default stylesheet |
|
||||
|
||||
#### Signals 与 Bindings
|
||||
|
||||
|
||||
@ -177,6 +177,8 @@ tp 不会把外部属性收编成新的匿名层,也不会静默覆盖它。
|
||||
- `tp-define-property` 只接受带 namespace 的 symbol id,例如 `text/face` 或 `ebox/width`;schema replacement 在完整验证后一次写入,失败不会破坏旧 definition。
|
||||
- structured selector 原生支持 type/id/class/attribute/state、compound、descendant/child/adjacent/general sibling,以及 `:is`、`:where` 和 `:not`;`tp-selector-specificity` 与 rule matching 使用同一 AST。
|
||||
- cascade 顺序固定为 importance、origin、layer、specificity、scope proximity、source order;normal 与 important declaration 的 layer 顺序按 CSS 规则相反,unlayered normal 高于 layered normal。
|
||||
- `tp-stylesheet-create` 建立相互隔离的 rule、layer order 与 source order domain;`tp-stylesheet-add-rule :stylesheet SHEET` 只写入该实例,`tp-compute-style :rules SHEET` 只读取该实例,避免不同 consumer 通过默认全局 stylesheet 相互污染。
|
||||
- 独立 stylesheet 的生命周期归创建者所有;`tp-style-reset` 只清理 TP 的全局 schema、named style 与 default stylesheet,调用方必须用 `tp-style-reset-rules SHEET` 显式清理自己的实例。
|
||||
- `initial`、`inherit`、`unset`、`revert` 和 `revert-layer` 必须由 `tp-wide-value` 显式构造,普通同名 Elisp symbol 保持 literal。
|
||||
- 普通 function value 永远不执行;只有 `tp-computed` 包装的 function 在计算时执行一次,其返回值不二次调用。
|
||||
- `--name` custom property 默认继承;`tp-var` 支持 fallback 和 cycle invalidation。属性 schema 的 normalizer/validator 在变量与 wide value 求值后执行。
|
||||
|
||||
@ -169,7 +169,7 @@ Stage 2 canonical façade 是内部模型,不改变公开入口和历史返回
|
||||
|
||||
### tp-style.el:纯 schema 与 cascade kernel
|
||||
|
||||
只依赖 tp-core,不接触 buffer、marker、mount 或订阅。它拥有 namespaced property schema、structured subject/selector、origin/importance/layer/specificity/scope/source-order cascade、逐属性继承、tagged CSS-wide values、custom property/`tp-var`、显式 `tp-computed`、named style、provenance 和最终 Emacs property projection。
|
||||
只依赖 tp-core,不接触 buffer、marker、mount 或订阅。它拥有 namespaced property schema、structured subject/selector、origin/importance/layer/specificity/scope/source-order cascade、逐属性继承、tagged CSS-wide values、custom property/`tp-var`、显式 `tp-computed`、named style、provenance 和最终 Emacs property projection。默认 stylesheet 只服务便利入口;独立 consumer 使用 `tp-stylesheet-create` 持有隔离的 rule、layer 与 source-order domain。
|
||||
|
||||
普通 function value 保持 literal;只有 `tp-computed` 才会求值一次。schema/rule 注册先完整校验再原子替换。shorthand 在进入候选集前展开一次,计算结果随后经过 variable/wide-value resolution、normalizer 和 validator。该模块提供后续 signal/binding 与 retained surface 共用的唯一 style 语义,不建立第二套 renderer。
|
||||
|
||||
@ -582,7 +582,7 @@ insert/copy/yank/stickiness/narrowing/indirect buffer 均不在 tp-query 中封
|
||||
| 模块 | 状态 | 描述 | 清理 |
|
||||
|------|------|------|------|
|
||||
| tp-core | —— | **无可变状态**(仅 `tp-debug-mode`/`tp-debug-echo` 两个用户选项;调试日志写入 *tp-debug* 缓冲区,由 `tp-debug-clear` 清除) | - |
|
||||
| tp-style | schema、named style、stylesheet rule、cascade layer/source order registries | 纯 style definition 和 rule 状态;不保存 object、buffer 或 mount | `tp-style-reset` / `tp-style-reset-rules` |
|
||||
| tp-style | schema、named style、default stylesheet 与调用方持有的独立 stylesheet instances | 纯 style definition 和 rule/layer/source-order 状态;不保存 object、buffer 或 mount;独立实例不被全局 reset 暗中清理 | `tp-style-reset` / `tp-style-reset-rules` |
|
||||
| tp-reactive | signals、owner bindings、dependency subscriber sets、variable adapters、transaction-local scheduler state、public counters | TP 1.0 exact reactive graph;normal update 不扫描 buffer | `tp-reactive-reset`;buffer-scoped signal 随 buffer kill |
|
||||
| tp-surface | buffer-local surfaces、object/mount/index、range anchors、property ledgers、root/scoped publication、plan/client-state/revision/report | TP 1.0 retained publication;global registry 仅 weak-reference | `tp-surface-unmount`;buffer kill authoritative teardown |
|
||||
| tp-reactive | `tp-reactive-deps` | 变量 → 依赖层 注册表 | `tp-reactive-reset` |
|
||||
|
||||
@ -168,6 +168,51 @@
|
||||
(should (tp-selector-match-p
|
||||
'(:where (:type button) (:class missing)) second)))))
|
||||
|
||||
(ert-deftest tp-style-test-subject-class-and-state-tokens-use-value-equality ()
|
||||
"Selectors match generic string tokens without requiring symbol identity."
|
||||
(tp-style-test--isolated
|
||||
(let ((subject (tp-subject-create
|
||||
:type 'button
|
||||
:classes (list (copy-sequence "primary"))
|
||||
:state (list (copy-sequence "active")))))
|
||||
(should (tp-selector-match-p '(:class "primary") subject))
|
||||
(should (tp-selector-match-p '(:state "active") subject)))))
|
||||
|
||||
(ert-deftest tp-style-test-stylesheet-instances-isolate-rules-and-layers ()
|
||||
"Independent stylesheets cannot leak rules or layer order into each other."
|
||||
(tp-style-test--isolated
|
||||
(tp-style-test--color-schema)
|
||||
(let ((left (tp-stylesheet-create))
|
||||
(right (tp-stylesheet-create))
|
||||
(subject (tp-subject-create :type 'button)))
|
||||
(tp-stylesheet-add-rule '(:type button) '(demo/color "blue")
|
||||
:layer 'base :stylesheet left)
|
||||
(tp-stylesheet-add-rule '(:type button) '(demo/color "red")
|
||||
:layer 'components :stylesheet left)
|
||||
(tp-stylesheet-add-rule '(:type button) '(demo/color "green")
|
||||
:layer 'components :stylesheet right)
|
||||
(tp-stylesheet-add-rule '(:type button) '(demo/color "purple")
|
||||
:layer 'base :stylesheet right)
|
||||
(should (equal (plist-get
|
||||
(tp-style-test--values subject :rules left)
|
||||
'demo/color)
|
||||
"red"))
|
||||
(should (equal (plist-get
|
||||
(tp-style-test--values subject :rules right)
|
||||
'demo/color)
|
||||
"purple"))
|
||||
(should (equal (plist-get (tp-style-test--values subject) 'demo/color)
|
||||
"black"))
|
||||
(tp-style-reset-rules left)
|
||||
(should (equal (plist-get
|
||||
(tp-style-test--values subject :rules left)
|
||||
'demo/color)
|
||||
"black"))
|
||||
(should (equal (plist-get
|
||||
(tp-style-test--values subject :rules right)
|
||||
'demo/color)
|
||||
"purple")))))
|
||||
|
||||
(ert-deftest tp-style-test-origin-importance-and-specificity-are-ordered ()
|
||||
"Importance, origin, and selector specificity decide the winner in order."
|
||||
(tp-style-test--isolated
|
||||
|
||||
119
tp-style.el
119
tp-style.el
@ -40,6 +40,12 @@
|
||||
"Computed values, active properties, custom properties, and provenance."
|
||||
values custom-properties active-properties provenance)
|
||||
|
||||
(cl-defstruct (tp-stylesheet
|
||||
(:constructor tp-stylesheet-create ())
|
||||
(:conc-name tp--stylesheet-))
|
||||
"Independent ordered rule and cascade-layer collection."
|
||||
rules layers (source-order 0))
|
||||
|
||||
(cl-defstruct (tp--computed-source (:constructor tp--make-computed-source))
|
||||
function)
|
||||
|
||||
@ -49,10 +55,10 @@
|
||||
name fallback-present-p fallback)
|
||||
|
||||
(cl-defstruct (tp--style-rule (:constructor tp--make-style-rule))
|
||||
selector declarations origin layer scope specificity source-order)
|
||||
selector declarations origin layer layer-rank scope specificity source-order)
|
||||
|
||||
(cl-defstruct (tp--candidate (:constructor tp--make-candidate))
|
||||
property value origin important layer specificity scope-distance
|
||||
property value origin important layer layer-rank specificity scope-distance
|
||||
source-order declaration-order selector)
|
||||
|
||||
(defconst tp--style-origin-order
|
||||
@ -178,14 +184,24 @@ OPTIONS support :initial, :inherits, :normalizer, :validator, :equality,
|
||||
(tp-register-text-property property))
|
||||
(copy-tree value))))
|
||||
|
||||
(defun tp-style-reset-rules ()
|
||||
"Clear stylesheet rules and their cascade-layer order."
|
||||
(setq tp--stylesheet-rules nil
|
||||
tp--cascade-layers nil
|
||||
tp--style-source-order 0))
|
||||
(defun tp-style-reset-rules (&optional stylesheet)
|
||||
"Clear rules and cascade-layer order in optional STYLESHEET.
|
||||
With nil STYLESHEET, reset TP's process-wide default stylesheet."
|
||||
(if stylesheet
|
||||
(progn
|
||||
(unless (tp-stylesheet-p stylesheet)
|
||||
(signal 'wrong-type-argument
|
||||
(list 'tp-stylesheet-p stylesheet)))
|
||||
(setf (tp--stylesheet-rules stylesheet) nil
|
||||
(tp--stylesheet-layers stylesheet) nil
|
||||
(tp--stylesheet-source-order stylesheet) 0))
|
||||
(setq tp--stylesheet-rules nil
|
||||
tp--cascade-layers nil
|
||||
tp--style-source-order 0)))
|
||||
|
||||
(defun tp-style-reset ()
|
||||
"Clear all TP style schemas, definitions, rules, and ordering state."
|
||||
"Clear TP's schemas, named styles, and default stylesheet state.
|
||||
Caller-owned stylesheet instances retain their rules until reset explicitly."
|
||||
(clrhash tp--property-schemas)
|
||||
(clrhash tp--named-styles)
|
||||
(setq tp--property-schema-order nil)
|
||||
@ -229,8 +245,8 @@ OPTIONS support :initial, :inherits, :normalizer, :validator, :equality,
|
||||
|
||||
(cl-defun tp-subject-create (&key type id classes attributes state parent children)
|
||||
"Create a generic cascade subject from TYPE, ID, and metadata.
|
||||
CLASSES and STATE are symbol lists. ATTRIBUTES is an alist. PARENT and
|
||||
CHILDREN must be TP subjects when present."
|
||||
CLASSES and STATE are token lists compared with `equal'. ATTRIBUTES is an
|
||||
alist. PARENT and CHILDREN must be TP subjects when present."
|
||||
(when (and parent (not (tp-subject-p parent)))
|
||||
(signal 'wrong-type-argument (list 'tp-subject-p parent)))
|
||||
(let ((subject (tp--make-subject
|
||||
@ -330,8 +346,8 @@ CHILDREN must be TP subjects when present."
|
||||
(:universal t)
|
||||
(:type (equal (nth 1 selector) (tp-subject-type subject)))
|
||||
(:id (equal (nth 1 selector) (tp-subject-id subject)))
|
||||
(:class (memq (nth 1 selector) (tp-subject-classes subject)))
|
||||
(:state (memq (nth 1 selector) (tp-subject-state subject)))
|
||||
(:class (member (nth 1 selector) (tp-subject-classes subject)))
|
||||
(:state (member (nth 1 selector) (tp-subject-state subject)))
|
||||
(:attr (tp--selector-match-attribute selector subject))
|
||||
(:and (cl-every (lambda (item) (tp-selector-match-p item subject))
|
||||
(cdr selector)))
|
||||
@ -456,31 +472,57 @@ CHILDREN must be TP subjects when present."
|
||||
(signal 'tp-invalid-style (list :origin origin)))
|
||||
origin)
|
||||
|
||||
(defun tp--register-cascade-layer (layer)
|
||||
"Register LAYER in first-seen order when non-nil."
|
||||
(when (and layer (not (memq layer tp--cascade-layers)))
|
||||
(setq tp--cascade-layers (append tp--cascade-layers (list layer)))))
|
||||
(defun tp--register-cascade-layer (layer stylesheet)
|
||||
"Register LAYER in first-seen order for optional STYLESHEET.
|
||||
Return LAYER's zero-based rank, or nil for an unlayered rule."
|
||||
(when layer
|
||||
(let ((layers (if stylesheet
|
||||
(tp--stylesheet-layers stylesheet)
|
||||
tp--cascade-layers)))
|
||||
(unless (memq layer layers)
|
||||
(setq layers (append layers (list layer)))
|
||||
(if stylesheet
|
||||
(setf (tp--stylesheet-layers stylesheet) layers)
|
||||
(setq tp--cascade-layers layers)))
|
||||
(cl-position layer layers))))
|
||||
|
||||
(defun tp--next-style-source-order (stylesheet)
|
||||
"Increment and return source order for optional STYLESHEET."
|
||||
(if stylesheet
|
||||
(cl-incf (tp--stylesheet-source-order stylesheet))
|
||||
(cl-incf tp--style-source-order)))
|
||||
|
||||
(defun tp--append-stylesheet-rule (rule stylesheet)
|
||||
"Append RULE to optional STYLESHEET and return RULE."
|
||||
(if stylesheet
|
||||
(setf (tp--stylesheet-rules stylesheet)
|
||||
(append (tp--stylesheet-rules stylesheet) (list rule)))
|
||||
(setq tp--stylesheet-rules
|
||||
(append tp--stylesheet-rules (list rule))))
|
||||
rule)
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun tp-stylesheet-add-rule
|
||||
(selector declarations &key (origin 'author) layer scope)
|
||||
(selector declarations &key (origin 'author) layer scope stylesheet)
|
||||
"Add a structured SELECTOR rule with DECLARATIONS.
|
||||
ORIGIN defaults to `author'. LAYER is ordered by first appearance. SCOPE,
|
||||
when non-nil, is a selector that must match the subject or an ancestor."
|
||||
when non-nil, is a selector that must match the subject or an ancestor.
|
||||
STYLESHEET isolates rules and layer order from TP's default stylesheet."
|
||||
(tp--validate-selector selector)
|
||||
(when scope (tp--validate-selector scope))
|
||||
(tp--validate-rule-origin origin)
|
||||
(let ((expanded (tp--expand-declarations declarations)))
|
||||
(tp--register-cascade-layer layer)
|
||||
(let ((rule (tp--make-style-rule
|
||||
:selector (copy-tree selector)
|
||||
:declarations (copy-tree expanded)
|
||||
:origin origin :layer layer :scope (copy-tree scope)
|
||||
:specificity (tp-selector-specificity selector)
|
||||
:source-order (cl-incf tp--style-source-order))))
|
||||
(setq tp--stylesheet-rules
|
||||
(append tp--stylesheet-rules (list rule)))
|
||||
rule)))
|
||||
(when (and stylesheet (not (tp-stylesheet-p stylesheet)))
|
||||
(signal 'wrong-type-argument (list 'tp-stylesheet-p stylesheet)))
|
||||
(let* ((expanded (tp--expand-declarations declarations))
|
||||
(layer-rank (tp--register-cascade-layer layer stylesheet))
|
||||
(rule (tp--make-style-rule
|
||||
:selector (copy-tree selector)
|
||||
:declarations (copy-tree expanded)
|
||||
:origin origin :layer layer :layer-rank layer-rank
|
||||
:scope (copy-tree scope)
|
||||
:specificity (tp-selector-specificity selector)
|
||||
:source-order (tp--next-style-source-order stylesheet))))
|
||||
(tp--append-stylesheet-rule rule stylesheet)))
|
||||
|
||||
(defun tp--scope-distance (scope subject)
|
||||
"Return distance from SUBJECT to matching SCOPE, or nil."
|
||||
@ -504,6 +546,7 @@ DECLARATION-ORDER is the property's position within RULE."
|
||||
:property property :value raw
|
||||
:origin (tp--style-rule-origin rule) :important important
|
||||
:layer (tp--style-rule-layer rule)
|
||||
:layer-rank (tp--style-rule-layer-rank rule)
|
||||
:specificity (tp--style-rule-specificity rule)
|
||||
:scope-distance (tp--scope-distance (tp--style-rule-scope rule) subject)
|
||||
:source-order (tp--style-rule-source-order rule)
|
||||
@ -529,7 +572,8 @@ DECLARATION-ORDER is the property's position within RULE."
|
||||
(pcase-let ((`(,raw . ,important) (tp--unwrap-important value)))
|
||||
(tp--make-candidate
|
||||
:property property :value raw :origin 'inline
|
||||
:important important :layer nil :specificity '(1 0 0)
|
||||
:important important :layer nil :layer-rank nil
|
||||
:specificity '(1 0 0)
|
||||
:scope-distance most-positive-fixnum
|
||||
:source-order (1+ tp--style-source-order)
|
||||
:declaration-order declaration-order
|
||||
@ -557,12 +601,13 @@ DECLARATION-ORDER is the property's position within RULE."
|
||||
(defun tp--layer-rank (candidate)
|
||||
"Return cascade layer rank for CANDIDATE."
|
||||
(let ((layer (tp--candidate-layer candidate))
|
||||
(rank (tp--candidate-layer-rank candidate))
|
||||
(important (tp--candidate-important candidate)))
|
||||
(cond
|
||||
((and important (null layer)) -1000000)
|
||||
((null layer) 1000000)
|
||||
(important (- (or (cl-position layer tp--cascade-layers) 0)))
|
||||
(t (or (cl-position layer tp--cascade-layers) 0)))))
|
||||
(important (- (or rank 0)))
|
||||
(t (or rank 0)))))
|
||||
|
||||
(defun tp--compare-number (left right)
|
||||
"Compare LEFT and RIGHT, returning 1, -1, or 0."
|
||||
@ -868,12 +913,16 @@ When PROVENANCE-P is non-nil, also retain winning declaration facts."
|
||||
parent-style provenance)
|
||||
"Compute a deterministic style for SUBJECT.
|
||||
DECLARATIONS are inline values. RULES defaults to the registered stylesheet;
|
||||
explicit nil disables stylesheet rules. PARENT-STYLE may be a computed style
|
||||
or values plist. When PROVENANCE is non-nil, winner metadata is retained."
|
||||
an isolated stylesheet instance selects only its rules, and explicit nil
|
||||
disables stylesheet rules. PARENT-STYLE may be a computed style or values
|
||||
plist. When PROVENANCE is non-nil, winner metadata is retained."
|
||||
(unless (tp-subject-p subject)
|
||||
(signal 'wrong-type-argument (list 'tp-subject-p subject)))
|
||||
(let* ((active-rules (if (eq rules tp--style-all-rules)
|
||||
tp--stylesheet-rules rules))
|
||||
tp--stylesheet-rules
|
||||
(if (tp-stylesheet-p rules)
|
||||
(tp--stylesheet-rules rules)
|
||||
rules)))
|
||||
(candidate-table
|
||||
(tp--group-candidates
|
||||
(tp--collect-candidates subject declarations active-rules)))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user