MCPcopy Index your code
hub / github.com/codeaashu/claude-code / renderScrolledChildren

Function renderScrolledChildren

src/ink/render-node-to-output.ts:1377–1448  ·  view source on GitHub ↗
(
  node: DOMElement,
  output: Output,
  offsetX: number,
  offsetY: number,
  hasRemovedChild: boolean,
  prevScreen: Screen | undefined,
  scrollTopY: number,
  scrollBottomY: number,
  inheritedBackgroundColor: Color | undefined,
  // When true (DECSTBM fast path), culled children keep their cache —
  // the blit+shift put stable rows in next.screen so stale cache is
  // never read. Avoids walking O(total_children * subtree_depth) per frame.
  preserveCulledCache = false,
)

Source from the content-addressed store, hash-verified

1375// viewport later they don't emit a stale clear for a position now occupied
1376// by a sibling.
1377function renderScrolledChildren(
1378 node: DOMElement,
1379 output: Output,
1380 offsetX: number,
1381 offsetY: number,
1382 hasRemovedChild: boolean,
1383 prevScreen: Screen | undefined,
1384 scrollTopY: number,
1385 scrollBottomY: number,
1386 inheritedBackgroundColor: Color | undefined,
1387 // When true (DECSTBM fast path), culled children keep their cache —
1388 // the blit+shift put stable rows in next.screen so stale cache is
1389 // never read. Avoids walking O(total_children * subtree_depth) per frame.
1390 preserveCulledCache = false,
1391): void {
1392 let seenDirtyChild = false
1393 // Track cumulative height shift of dirty children iterated so far. When
1394 // zero, a clean child's yogaTop is unchanged (no sibling above it grew),
1395 // so cached.top is fresh and the cull check skips yoga. Bottom-append
1396 // has the dirty child last → all prior clean children hit cache →
1397 // O(dirty) not O(mounted). Middle-growth leaves shift non-zero after
1398 // the dirty child → subsequent children yoga-read (needed for correct
1399 // culling since their yogaTop shifted).
1400 let cumHeightShift = 0
1401 for (const childNode of node.childNodes) {
1402 const childElem = childNode as DOMElement
1403 const cy = childElem.yogaNode
1404 if (cy) {
1405 const cached = nodeCache.get(childElem)
1406 let top: number
1407 let height: number
1408 if (
1409 cached?.top !== undefined &&
1410 !childElem.dirty &&
1411 cumHeightShift === 0
1412 ) {
1413 top = cached.top
1414 height = cached.height
1415 } else {
1416 top = cy.getComputedTop()
1417 height = cy.getComputedHeight()
1418 if (childElem.dirty) {
1419 cumHeightShift += height - (cached ? cached.height : 0)
1420 }
1421 // Refresh cached top so next frame's cumShift===0 path stays
1422 // correct. For culled children with preserveCulledCache=true this
1423 // is the ONLY refresh point — without it, a middle-growth frame
1424 // leaves stale tops that misfire next frame.
1425 if (cached) cached.top = top
1426 }
1427 const bottom = top + height
1428 if (bottom <= scrollTopY || top >= scrollBottomY) {
1429 // Culled — outside visible window. Drop stale cache entries from
1430 // the subtree so when this child re-enters it doesn't fire clears
1431 // at positions now occupied by siblings. The viewport-clear on
1432 // scroll-change handles the visible-area repaint.
1433 if (!preserveCulledCache) dropSubtreeCache(childElem)
1434 continue

Callers 1

renderNodeToOutputFunction · 0.85

Calls 5

dropSubtreeCacheFunction · 0.85
renderNodeToOutputFunction · 0.85
getMethod · 0.65
getComputedTopMethod · 0.45
getComputedHeightMethod · 0.45

Tested by

no test coverage detected