feat: classify Box axes as structural style

This commit is contained in:
Kinneyzhang 2026-08-26 16:13:02 +08:00
parent 9f2cdfb299
commit 47f9da2ef2
2 changed files with 51 additions and 3 deletions

View File

@ -161,6 +161,12 @@
(:name :display :id ebox/display :initial nil :contexts (node) (:name :display :id ebox/display :initial nil :contexts (node)
:group structure :dirty-kind structure :signature structure :group structure :dirty-kind structure :signature structure
:validator display) :validator display)
(:name :outer :id ebox/outer :initial block :contexts (node)
:group structure :dirty-kind structure :signature structure
:validator outer)
(:name :layout :id ebox/layout :initial normal :contexts (node)
:group structure :dirty-kind structure :signature structure
:validator layout)
(:name :flex-direction :id ebox/flex-direction :initial nil (:name :flex-direction :id ebox/flex-direction :initial nil
:contexts (flex) :group geometry :dirty-kind geometry :signature layout) :contexts (flex) :group geometry :dirty-kind geometry :signature layout)
(:name :flex-wrap :id ebox/flex-wrap :initial nil :contexts (flex) (:name :flex-wrap :id ebox/flex-wrap :initial nil :contexts (flex)
@ -548,6 +554,14 @@ every `ebox-create' needlessly copies the entire property metadata domain.")
(and (listp value) (= (length value) 2) (and (listp value) (= (length value) 2)
(cl-every #'symbolp value)))) (cl-every #'symbolp value))))
(defun ebox-style--outer-p (value)
"Return non-nil when VALUE is an Ebox outer participation value."
(memq value '(inline block)))
(defun ebox-style--layout-p (value)
"Return non-nil when VALUE is an Ebox child layout value."
(memq value '(normal row column flex grid)))
(defun ebox-style--font-p (value) (defun ebox-style--font-p (value)
"Return non-nil when VALUE is an Ebox font face specification." "Return non-nil when VALUE is an Ebox font face specification."
(or (null value) (symbolp value) (stringp value) (proper-list-p value))) (or (null value) (symbolp value) (stringp value) (proper-list-p value)))
@ -573,6 +587,8 @@ every `ebox-create' needlessly copies the entire property metadata domain.")
('positive-integer #'ebox-style--positive-integer-p) ('positive-integer #'ebox-style--positive-integer-p)
('grid-placement #'ebox-style--grid-placement-p) ('grid-placement #'ebox-style--grid-placement-p)
('display #'ebox-style--display-p) ('display #'ebox-style--display-p)
('outer #'ebox-style--outer-p)
('layout #'ebox-style--layout-p)
('font #'ebox-style--font-p) ('font #'ebox-style--font-p)
('font-family #'ebox-style--font-family-p) ('font-family #'ebox-style--font-family-p)
('font-height #'ebox-style--font-height-p) ('font-height #'ebox-style--font-height-p)
@ -1193,6 +1209,27 @@ SNAPSHOT reuses a previously detached ECSS values snapshot when supplied."
do (plist-put node property value))) do (plist-put node property value)))
node) node)
(defun ebox-style--apply-display-axes (node style snapshot)
"Apply computed display and public axes from STYLE SNAPSHOT to NODE."
(when (ebox-style--snapshot-active-p snapshot :display)
(plist-put node :display
(ebox-style-computed-value style :display)))
(let* ((outer-specified-p
(ebox-style--specified-property-p style 'ebox/outer))
(layout-specified-p
(ebox-style--specified-property-p style 'ebox/layout)))
(when (or outer-specified-p layout-specified-p)
(let* ((display (or (plist-get node :display) '(block flow)))
(outer (if outer-specified-p
(ebox-style-computed-value style :outer)
(car display)))
(layout (if layout-specified-p
(ebox-style-computed-value style :layout)
(cadr display))))
(plist-put node :display
(list outer (if (eq layout 'normal) 'flow layout))))))
node)
(defun ebox-style-apply-computed (node style) (defun ebox-style-apply-computed (node style)
"Apply ECSS computed STYLE consequences to semantic Ebox NODE." "Apply ECSS computed STYLE consequences to semantic Ebox NODE."
(unless (ecss-computed-style-p style) (unless (ecss-computed-style-p style)
@ -1201,9 +1238,7 @@ SNAPSHOT reuses a previously detached ECSS values snapshot when supplied."
(snapshot (snapshot
(ebox-style--computed-snapshot style (memq type '(flex grid))))) (ebox-style--computed-snapshot style (memq type '(flex grid)))))
(plist-put node :ebox-computed-style style) (plist-put node :ebox-computed-style style)
(when (ebox-style--snapshot-active-p snapshot :display) (ebox-style--apply-display-axes node style snapshot)
(plist-put node :display
(ebox-style-computed-value style :display)))
(pcase type (pcase type
('box ('box
(ebox-style--apply-engine-values (ebox-style--apply-engine-values

View File

@ -37,8 +37,21 @@
(should (eq (ebox-style-dirty-kind :border-color) 'paint)) (should (eq (ebox-style-dirty-kind :border-color) 'paint))
(should (eq (ebox-style-dirty-kind :padding-inline-start) 'geometry)) (should (eq (ebox-style-dirty-kind :padding-inline-start) 'geometry))
(should (eq (ebox-style-dirty-kind :width) 'geometry)) (should (eq (ebox-style-dirty-kind :width) 'geometry))
(should (eq (ebox-style-dirty-kind :outer) 'structure))
(should (eq (ebox-style-dirty-kind :layout) 'structure))
(should (eq (ebox-style-dirty-kind :display) 'structure))) (should (eq (ebox-style-dirty-kind :display) 'structure)))
(ert-deftest ebox-style-projects-public-box-axes-to-internal-display ()
"Computed outer/layout properties should project to one display pair."
(let* ((style
(ebox-style-compute-subject
(ecss-subject-create :type "box")
(ebox-style-compile-declarations
'(:outer inline :layout flex))))
(node (ebox-build '(box "A"))))
(ebox-style-apply-computed node style)
(should (equal (ebox--computed-display node) '(inline flex)))))
(ert-deftest ebox-dsl-module-preserves-public-build-syntax () (ert-deftest ebox-dsl-module-preserves-public-build-syntax ()
"Extracted DSL compiler should preserve existing ebox-build syntax." "Extracted DSL compiler should preserve existing ebox-build syntax."
(let ((node (ebox-build (let ((node (ebox-build