Complete retained layer update and packaging contracts
Some checks are pending
CI / test (29.1) (push) Waiting to run
CI / test (30.2) (push) Waiting to run
CI / native-build (macos-latest) (push) Waiting to run
CI / native-build (ubuntu-latest) (push) Waiting to run
CI / native-build (windows-latest) (push) Waiting to run
CI / native-msrv (macos-latest) (push) Waiting to run
CI / native-msrv (ubuntu-latest) (push) Waiting to run
CI / native-msrv (windows-latest) (push) Waiting to run
Some checks are pending
CI / test (29.1) (push) Waiting to run
CI / test (30.2) (push) Waiting to run
CI / native-build (macos-latest) (push) Waiting to run
CI / native-build (ubuntu-latest) (push) Waiting to run
CI / native-build (windows-latest) (push) Waiting to run
CI / native-msrv (macos-latest) (push) Waiting to run
CI / native-msrv (ubuntu-latest) (push) Waiting to run
CI / native-msrv (windows-latest) (push) Waiting to run
This commit is contained in:
parent
4a25d573c2
commit
2a64573d42
@ -190,7 +190,7 @@ the fact once for its spatial root.")
|
|||||||
(car matches)))
|
(car matches)))
|
||||||
|
|
||||||
(defun ebox-layer--absolute-origin (node host bounds width height layer-width layer-height)
|
(defun ebox-layer--absolute-origin (node host bounds width height layer-width layer-height)
|
||||||
"Resolve NODE's origin in HOST's BASE, or nil for an invisible anchor.
|
"Resolve NODE's origin in HOST, or nil for an invisible anchor.
|
||||||
BOUNDS is the already resolved anchor rectangle, or nil.
|
BOUNDS is the already resolved anchor rectangle, or nil.
|
||||||
WIDTH and HEIGHT bound the host; LAYER-WIDTH and LAYER-HEIGHT bound the panel."
|
WIDTH and HEIGHT bound the host; LAYER-WIDTH and LAYER-HEIGHT bound the panel."
|
||||||
(let ((x (ebox-layer--offset node :left host width))
|
(let ((x (ebox-layer--offset node :left host width))
|
||||||
|
|||||||
@ -1570,8 +1570,10 @@ the separate unwrapped measurement keeps that resolution non-recursive."
|
|||||||
(cond
|
(cond
|
||||||
((and (eq (ebox-get props :width) 'max-content)
|
((and (eq (ebox-get props :width) 'max-content)
|
||||||
(not (memq (ebox--box-layout-kind props) '(normal column))))
|
(not (memq (ebox--box-layout-kind props) '(normal column))))
|
||||||
|
;; This is an unbounded *visible* formatting context, not necessarily
|
||||||
|
;; an intrinsic-size probe. Preserve the caller's measurement mode;
|
||||||
|
;; suppressing paint here would discard positioned descendants.
|
||||||
(let ((ebox-viewport-width nil)
|
(let ((ebox-viewport-width nil)
|
||||||
(ebox--intrinsic-layout-measurement t)
|
|
||||||
(ebox--inline-auto-width-intrinsic-p nil))
|
(ebox--inline-auto-width-intrinsic-p nil))
|
||||||
(funcall function)))
|
(funcall function)))
|
||||||
(content-viewport
|
(content-viewport
|
||||||
|
|||||||
@ -18,6 +18,8 @@
|
|||||||
(require 'ebox-runtime-index)
|
(require 'ebox-runtime-index)
|
||||||
(require 'ebox-size)
|
(require 'ebox-size)
|
||||||
|
|
||||||
|
(defvar ebox-incremental--render-portals-p)
|
||||||
|
|
||||||
(declare-function ebox-string-height "ebox" (string))
|
(declare-function ebox-string-height "ebox" (string))
|
||||||
(declare-function ebox-surface--retained-property-value-equal-p
|
(declare-function ebox-surface--retained-property-value-equal-p
|
||||||
"ebox-surface" (left right))
|
"ebox-surface" (left right))
|
||||||
|
|||||||
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
(require 'cl-lib)
|
(require 'cl-lib)
|
||||||
|
|
||||||
|
(defvar ebox-layer--active-p)
|
||||||
|
(defvar ebox-incremental--render-portals-p)
|
||||||
|
(defvar ebox--render-source-index)
|
||||||
|
|
||||||
(declare-function ebox-interaction--refresh-hover! "ebox-interaction"
|
(declare-function ebox-interaction--refresh-hover! "ebox-interaction"
|
||||||
(string start end &optional face))
|
(string start end &optional face))
|
||||||
|
|
||||||
@ -266,6 +270,16 @@ including strings returned from a render-cache hit."
|
|||||||
(ebox--css-size-context-active-p t)
|
(ebox--css-size-context-active-p t)
|
||||||
(ebox--render-runtime-revision
|
(ebox--render-runtime-revision
|
||||||
(plist-get ,render-state :runtime-revision))
|
(plist-get ,render-state :runtime-revision))
|
||||||
|
(ebox--render-source-index
|
||||||
|
(plist-get ,render-state :source-index))
|
||||||
|
(ebox-layer--active-p
|
||||||
|
(if (plist-member ,render-state :layered-p)
|
||||||
|
(plist-get ,render-state :layered-p)
|
||||||
|
'unknown))
|
||||||
|
(ebox-incremental--render-portals-p
|
||||||
|
(if (plist-member ,render-state :root-portals-p)
|
||||||
|
(plist-get ,render-state :root-portals-p)
|
||||||
|
'unknown))
|
||||||
(ebox--surface-materialization-active t)
|
(ebox--surface-materialization-active t)
|
||||||
(ebox--render-cache-table
|
(ebox--render-cache-table
|
||||||
(plist-get ,render-state :render-cache))
|
(plist-get ,render-state :render-cache))
|
||||||
|
|||||||
@ -301,6 +301,9 @@ rather than relying on an implicit default.")
|
|||||||
(:symbol ebox--box-content-empty-width
|
(:symbol ebox--box-content-empty-width
|
||||||
:reason dynamic-scalar-result
|
:reason dynamic-scalar-result
|
||||||
:evidence numeric-inline-extent-returned-with-one-content-materialization)
|
:evidence numeric-inline-extent-returned-with-one-content-materialization)
|
||||||
|
(:symbol ebox-layer--portals
|
||||||
|
:reason dynamically-bound-render-collection
|
||||||
|
:evidence let-bound-per-spatial-root-and-discarded-with-the-candidate-render)
|
||||||
(:symbol ebox--string-pixel-width-cache-ring-index
|
(:symbol ebox--string-pixel-width-cache-ring-index
|
||||||
:reason numeric-eviction-cursor
|
:reason numeric-eviction-cursor
|
||||||
:evidence value-is-an-integer-ring-position)
|
:evidence value-is-an-integer-ring-position)
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
(require 'tp)
|
(require 'tp)
|
||||||
|
|
||||||
(defvar ebox-region-types)
|
(defvar ebox-region-types)
|
||||||
|
(declare-function ebox--runtime-node-ids "ebox" (node))
|
||||||
(defvar ebox--region-id-counter)
|
(defvar ebox--region-id-counter)
|
||||||
(defvar ebox--runtime-node-id-counter)
|
(defvar ebox--runtime-node-id-counter)
|
||||||
(defvar ebox--region-box-table)
|
(defvar ebox--region-box-table)
|
||||||
|
|||||||
2
ebox.el
2
ebox.el
@ -3854,6 +3854,8 @@ Defaults to the current buffer."
|
|||||||
:text-align :vertical-align
|
:text-align :vertical-align
|
||||||
:overflow :wrap-mode
|
:overflow :wrap-mode
|
||||||
:scroll-offset :visibility)
|
:scroll-offset :visibility)
|
||||||
|
(cl-loop for (property _value) on ebox-style--box-runtime-defaults by #'cddr
|
||||||
|
collect property)
|
||||||
ebox-style--item-projection-properties)
|
ebox-style--item-projection-properties)
|
||||||
"Longhand box properties accepted by `ebox-region-update'.")
|
"Longhand box properties accepted by `ebox-region-update'.")
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,27 @@
|
|||||||
(plist-get (ebox-surface-buffer-snapshot (current-buffer))
|
(plist-get (ebox-surface-buffer-snapshot (current-buffer))
|
||||||
:input))))))
|
:input))))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-publication-updates-every-placement-property ()
|
||||||
|
"Each layer declaration reaches the mounted runtime through a region update."
|
||||||
|
(dolist (properties '((:position relative) (:left (ch 2)) (:top (lh 1))
|
||||||
|
(:z-index -1) (:layer root) (:anchor "lower")
|
||||||
|
(:placement top-end)))
|
||||||
|
(ert-info ((format "Update %S" properties))
|
||||||
|
(ebox-layer-publication-test--with-buffer
|
||||||
|
(ebox-render-to-buffer
|
||||||
|
(current-buffer) (ebox-layer-publication-test--input nil t))
|
||||||
|
(let* ((handle (ebox-region-resolve (current-buffer) "upper"))
|
||||||
|
(region-id (cdr (ebox-selector--region-target handle)))
|
||||||
|
(revision (ebox-surface-buffer-revision (current-buffer))))
|
||||||
|
(should (apply #'ebox-region-update handle properties))
|
||||||
|
(should (> (ebox-surface-buffer-revision (current-buffer)) revision))
|
||||||
|
(should (equal (plist-get
|
||||||
|
(ebox--buffer-region-render-owner-node
|
||||||
|
(current-buffer) region-id)
|
||||||
|
(car properties))
|
||||||
|
(cadr properties)))
|
||||||
|
(ebox-layer-publication-test--assert-fresh-render))))))
|
||||||
|
|
||||||
(ert-deftest ebox-layer-publication-hidden-updates-reveal-current-input ()
|
(ert-deftest ebox-layer-publication-hidden-updates-reveal-current-input ()
|
||||||
"Hidden content and paint updates survive without painting over upper text."
|
"Hidden content and paint updates survive without painting over upper text."
|
||||||
(ebox-layer-publication-test--with-buffer
|
(ebox-layer-publication-test--with-buffer
|
||||||
|
|||||||
@ -77,5 +77,88 @@
|
|||||||
:width (ch 6) "HIDDEN")))))
|
:width (ch 6) "HIDDEN")))))
|
||||||
(should (equal (substring-no-properties output) "LATEST"))))
|
(should (equal (substring-no-properties output) "LATEST"))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-max-content-row-paints-positioned-descendants ()
|
||||||
|
(let ((output (ebox-layer-test--render
|
||||||
|
'(row :width max-content
|
||||||
|
(box :width (ch 4) :height (lh 1)
|
||||||
|
(box "ABCD")
|
||||||
|
(box :position absolute :left (ch 1)
|
||||||
|
:width (ch 2) "XX"))))))
|
||||||
|
(should (equal (substring-no-properties output) "AXXD"))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-anchor-dependency-resolves-before-paint-order ()
|
||||||
|
(let ((output (ebox-layer-test--render
|
||||||
|
'(box :width (ch 10) :height (lh 4)
|
||||||
|
(box "0123456789\nabcdefghij\nABCDEFGHIJ\n0123456789")
|
||||||
|
(box :position absolute :anchor parent-panel :width (ch 4)
|
||||||
|
:z-index 2 "MENU")
|
||||||
|
(box :id parent-panel :position absolute :left (ch 2)
|
||||||
|
:top (lh 1) :width (ch 4) :z-index 1 "BASE")))))
|
||||||
|
(should (equal (substring-no-properties output)
|
||||||
|
"0123456789\nabBASEghij\nABMENUGHIJ\n0123456789"))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-anchor-cycles-are-rejected ()
|
||||||
|
(should-error
|
||||||
|
(ebox-layer-test--render
|
||||||
|
'(box :width (ch 10) :height (lh 4)
|
||||||
|
(box :id a :position absolute :anchor b "A")
|
||||||
|
(box :id b :position absolute :anchor a "B")))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-absolute-margins-do-not-cover-underlay ()
|
||||||
|
(let ((output (ebox-layer-test--render
|
||||||
|
'(box :width (ch 8) :height (lh 3)
|
||||||
|
(box "abcdefgh\nABCDEFGH\n01234567")
|
||||||
|
(box :position absolute :width (ch 4) :height (lh 1)
|
||||||
|
:margin ((lh 1) (ch 1)) :background-color "red"
|
||||||
|
"TOP!")))))
|
||||||
|
(should (equal (substring-no-properties output)
|
||||||
|
"abcdefgh\nATOP!FGH\n01234567"))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-absolute-keeps-all-flow-layout-sizes ()
|
||||||
|
(dolist (tag '(box row column flex grid))
|
||||||
|
(let* ((form `(,tag :width (ch 8)
|
||||||
|
(box :width (ch 8) :height (lh 1) "abcdefgh")
|
||||||
|
(box :position absolute :left (ch 2)
|
||||||
|
:width (ch 2) :height (lh 9) "XX")))
|
||||||
|
(output (ebox-layer-test--render form)))
|
||||||
|
(ert-info ((format "Layout %s" tag))
|
||||||
|
(should (= (length (ebox-string-lines output)) 1))
|
||||||
|
(should (equal (substring-no-properties output) "abXXefgh"))))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-root-projection-inside-an-absolute-panel ()
|
||||||
|
(let ((output (ebox-layer-test--render
|
||||||
|
'(box :width (ch 10) :height (lh 4)
|
||||||
|
(box "0123456789\nabcdefghij\nABCDEFGHIJ\n0123456789")
|
||||||
|
(box :position absolute :left (ch 2) :top (lh 1)
|
||||||
|
:width (ch 4) :height (lh 1)
|
||||||
|
(box :id trigger "BASE")
|
||||||
|
(box :position absolute :layer root :anchor trigger
|
||||||
|
:width (ch 4) :height (lh 1) "MENU"))))))
|
||||||
|
(should (equal (substring-no-properties output)
|
||||||
|
"0123456789\nabBASEghij\nABMENUGHIJ\n0123456789"))))
|
||||||
|
|
||||||
|
(ert-deftest ebox-layer-native-to-layer-transition-keeps-composition ()
|
||||||
|
(skip-unless (and (fboundp 'ebox-native-reflow-layout-ready-p)
|
||||||
|
(ebox-native-reflow-layout-ready-p)))
|
||||||
|
(let ((ebox-viewport-width 80) (ebox-viewport-height 10)
|
||||||
|
(ebox-runtime-idle-prewarm nil)
|
||||||
|
(ebox-runtime-idle-reflow-cache-prewarm nil))
|
||||||
|
(with-temp-buffer
|
||||||
|
(ebox-render-to-buffer
|
||||||
|
(current-buffer)
|
||||||
|
(ebox-build '(column :width (px 8) :height (lh 2)
|
||||||
|
(box :id "lower" :width (px 8) :height (lh 1) "LOWER001")
|
||||||
|
(box :id "upper" :width (px 8) :height (lh 1) "UPPER001"))))
|
||||||
|
(should (eq (plist-get (ebox--buffer-render-state (current-buffer))
|
||||||
|
:projection-kind) 'native-frame))
|
||||||
|
(should (ebox-region-update "upper" :position 'absolute))
|
||||||
|
(should (plist-get (ebox--buffer-render-state (current-buffer)) :layered-p))
|
||||||
|
(should-not (string-match-p "LOWER001" (buffer-string)))
|
||||||
|
(should (string-match-p "UPPER001" (buffer-string)))
|
||||||
|
(ebox-region-update "lower" :content "LOWER002")
|
||||||
|
(ebox-region-update "upper" :visibility 'hidden)
|
||||||
|
(should (string-match-p "LOWER002" (buffer-string)))
|
||||||
|
(should-not (string-match-p "UPPER001" (buffer-string))))))
|
||||||
|
|
||||||
(provide 'ebox-layer-tests)
|
(provide 'ebox-layer-tests)
|
||||||
;;; ebox-layer-tests.el ends here
|
;;; ebox-layer-tests.el ends here
|
||||||
|
|||||||
@ -25,6 +25,9 @@
|
|||||||
(:storage (:state-key :content-index)
|
(:storage (:state-key :content-index)
|
||||||
:why address-scalar-not-a-store :owner ebox-surface
|
:why address-scalar-not-a-store :owner ebox-surface
|
||||||
:evidence plist-key-holds-a-numeric-content-address)
|
:evidence plist-key-holds-a-numeric-content-address)
|
||||||
|
(:storage (:state-key :z-index)
|
||||||
|
:why paint-order-scalar-not-a-store :owner ebox-layer
|
||||||
|
:evidence style-schema-requires-an-integer-used-only-for-layer-ordering)
|
||||||
(:storage (:state-key :max-jobs)
|
(:storage (:state-key :max-jobs)
|
||||||
:why native-limit-not-a-store :owner ebox-native-reflow
|
:why native-limit-not-a-store :owner ebox-native-reflow
|
||||||
:evidence plist-key-holds-a-numeric-capacity)
|
:evidence plist-key-holds-a-numeric-capacity)
|
||||||
|
|||||||
@ -162,7 +162,8 @@
|
|||||||
"ebox-node-factory.el"
|
"ebox-node-factory.el"
|
||||||
"ebox-child-range.el"
|
"ebox-child-range.el"
|
||||||
"ebox-tree.el" "ebox-measure.el"
|
"ebox-tree.el" "ebox-measure.el"
|
||||||
"ebox-fragment.el" "ebox-render-context.el" "ebox-layout.el"
|
"ebox-fragment.el" "ebox-render-context.el" "ebox-composite.el"
|
||||||
|
"ebox-layer.el" "ebox-layout.el"
|
||||||
"ebox-flex.el" "ebox-grid.el" "ebox-canonical.el"
|
"ebox-flex.el" "ebox-grid.el" "ebox-canonical.el"
|
||||||
"ebox-buffer-backend.el" "ebox-patch-plan.el"
|
"ebox-buffer-backend.el" "ebox-patch-plan.el"
|
||||||
"ebox-incremental.el"
|
"ebox-incremental.el"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user