source dump of claude code
at main 54 lines 1.7 kB view raw
1import type { DOMElement } from './dom.js' 2import type { Rectangle } from './layout/geometry.js' 3 4/** 5 * Cached layout bounds for each rendered node (used for blit + clearing). 6 * `top` is the yoga-local getComputedTop() — stored so ScrollBox viewport 7 * culling can skip yoga reads for clean children whose position hasn't 8 * shifted (O(dirty) instead of O(mounted) first-pass). 9 */ 10export type CachedLayout = { 11 x: number 12 y: number 13 width: number 14 height: number 15 top?: number 16} 17 18export const nodeCache = new WeakMap<DOMElement, CachedLayout>() 19 20/** Rects of removed children that need clearing on next render */ 21export const pendingClears = new WeakMap<DOMElement, Rectangle[]>() 22 23/** 24 * Set when a pendingClear is added for an absolute-positioned node. 25 * Signals renderer to disable blit for the next frame: the removed node 26 * may have painted over non-siblings (e.g. an overlay over a ScrollBox 27 * earlier in tree order), so their blits from prevScreen would restore 28 * the overlay's pixels. Normal-flow removals are already handled by 29 * hasRemovedChild at the parent level; only absolute positioning paints 30 * cross-subtree. Reset at the start of each render. 31 */ 32let absoluteNodeRemoved = false 33 34export function addPendingClear( 35 parent: DOMElement, 36 rect: Rectangle, 37 isAbsolute: boolean, 38): void { 39 const existing = pendingClears.get(parent) 40 if (existing) { 41 existing.push(rect) 42 } else { 43 pendingClears.set(parent, [rect]) 44 } 45 if (isAbsolute) { 46 absoluteNodeRemoved = true 47 } 48} 49 50export function consumeAbsoluteRemovedFlag(): boolean { 51 const had = absoluteNodeRemoved 52 absoluteNodeRemoved = false 53 return had 54}