From c57fb24abd77e742b617d38b56c312d273c29027 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 08:03:43 +0000 Subject: [PATCH] Add child_count getter to CSSNode Traverses the arena's linked list using raw indices directly, avoiding CSSNode object allocation and intermediate array creation. https://claude.ai/code/session_01JZ7KyHoubj42U8DN2GRv7n --- src/api.test.ts | 20 ++++++++++++++++++++ src/css-node.ts | 11 +++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/api.test.ts b/src/api.test.ts index 65da5ac..a6db47d 100644 --- a/src/api.test.ts +++ b/src/api.test.ts @@ -74,6 +74,26 @@ describe('CSSNode', () => { }) }) + describe('child_count', () => { + test('should return the number of children', () => { + const source = 'body { color: red; margin: 0; padding: 10px; }' + const root = parse(source, { parse_selectors: false, parse_values: false }) + const block = root.first_child!.block! + expect(block.child_count).toBe(3) + }) + + test('should return 0 for a node with no children', () => { + const root = parse('', { parse_selectors: false, parse_values: false }) + expect(root.child_count).toBe(0) + }) + + test('should match children.length', () => { + const source = 'body { color: red; } div { margin: 0; }' + const root = parse(source, { parse_selectors: false, parse_values: false }) + expect(root.child_count).toBe(root.children.length) + }) + }) + describe('has_prelude', () => { test('should return true for @media with prelude', () => { const source = '@media (min-width: 768px) { body { color: red; } }' diff --git a/src/css-node.ts b/src/css-node.ts index b4194ec..e3a7d40 100644 --- a/src/css-node.ts +++ b/src/css-node.ts @@ -584,6 +584,17 @@ export class CSSNode { return this.arena.has_children(this.index) } + /** Count children without allocating an intermediate array */ + get child_count(): number { + let count = 0 + let child_index = this.arena.get_first_child(this.index) + while (child_index !== 0) { + count++ + child_index = this.arena.get_next_sibling(child_index) + } + return count + } + /** Get all children as an array */ get children(): CSSNode[] { let result: CSSNode[] = []