Skip to content

Commit 9ffd7f0

Browse files
authored
perf: make comments terser (#273)
Comments ship to both dist JS files and .d.ts files. Some comments were overly lengthy. 191.15 kB to 183.41 kB
1 parent 78c8cf6 commit 9ffd7f0

7 files changed

Lines changed: 38 additions & 222 deletions

File tree

src/arena.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,7 @@ export class CSSDataArena {
352352
}
353353
}
354354

355-
/**
356-
* Shrink the buffer to exactly the number of live nodes, releasing wasted capacity.
357-
* Call once after parsing is complete. Safe to call multiple times (no-op if already tight).
358-
*
359-
* @see https://doc.rust-lang.org/std/vec/struct.Vec.html#method.shrink_to_fit
360-
* @see https://en.cppreference.com/w/cpp/container/vector/shrink_to_fit
361-
*/
355+
/** Shrink the buffer to the live node count, releasing wasted capacity. Call once after parsing; no-op if already tight. */
362356
trim(): void {
363357
if (this.count === this.capacity) return
364358
let byte_count = this.count * BYTES_PER_NODE

src/css-node.ts

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,7 @@ export class CSSNode {
330330
return content
331331
}
332332

333-
/**
334-
* Namespace prefix for type and universal selectors.
335-
* - `null` — no namespace qualifier (plain `div` or `*`)
336-
* - `''` — empty namespace (`|div` or `|*`)
337-
* - `'ns'` — named namespace (`ns|div` or `ns|*`)
338-
* - `'*'` — any namespace (`*|div` or `*|*`)
339-
*/
333+
/** Namespace prefix for type/universal selectors: null (none), '' (`|div`), 'ns' (`ns|div`), or '*' (`*|div`). */
340334
get namespace(): string | null | undefined {
341335
let { type } = this
342336
if (type !== TYPE_SELECTOR && type !== UNIVERSAL_SELECTOR) return undefined
@@ -346,22 +340,16 @@ export class CSSNode {
346340
return this.source.substring(start, start + length)
347341
}
348342

349-
/**
350-
* Alias for name (for declarations: "color" in "color: blue")
351-
* More semantic than `name` for declaration nodes
352-
*/
343+
/** Alias for `name` on declarations ("color" in "color: blue"), more semantic than `name` there. */
353344
get property(): string | undefined {
354345
let { type } = this
355346
if (type !== DECLARATION && type !== MEDIA_FEATURE) return
356347
return this.get_content()
357348
}
358349

359350
/**
360-
* Get the value text (for declarations: "1px solid blue" in "border: 1px solid blue")
361-
* For dimension/number nodes: returns the numeric value as a number
362-
* For string nodes: returns the string content without quotes
363-
* For URL nodes with quoted string: returns the string with quotes (consistent with STRING node)
364-
* For URL nodes with unquoted URL: returns the URL content without quotes
351+
* Declarations: the value text ("1px solid blue"). Dimension/number: the numeric value.
352+
* String: content without quotes. URL: quoted string keeps quotes, unquoted URL doesn't.
365353
*/
366354
get value(): CSSNode | string | number | null | undefined {
367355
let { type, text, first_child } = this
@@ -433,12 +421,7 @@ export class CSSNode {
433421
return this.source.substring(start, start + length)
434422
}
435423

436-
/**
437-
* Get the prelude node:
438-
* - For at-rules: AT_RULE_PRELUDE wrapper containing structured prelude children (media queries, layer names, etc.)
439-
* - For style rules: SELECTOR_LIST or SELECTOR node
440-
* Returns null if no prelude exists
441-
*/
424+
/** At-rules: AT_RULE_PRELUDE wrapper (media queries, layer names, …). Style rules: SELECTOR_LIST/SELECTOR. Null if none. */
442425
get prelude(): CSSNode | null | undefined {
443426
if (this.type === AT_RULE) {
444427
let first = this.first_child
@@ -454,11 +437,7 @@ export class CSSNode {
454437
return undefined
455438
}
456439

457-
/**
458-
* Get the attribute operator (for attribute selectors: =, ~=, |=, ^=, $=, *=)
459-
* Returns the operator string, or null if no operator is present ([attr] form).
460-
* Derived from source text between the attribute name and value.
461-
*/
440+
/** Attribute selector operator (=, ~=, |=, ^=, $=, *=), or null for the bare `[attr]` form. */
462441
get attr_operator(): string | null | undefined {
463442
if (this.type !== ATTRIBUTE_SELECTOR) return undefined
464443

@@ -485,11 +464,7 @@ export class CSSNode {
485464
return null
486465
}
487466

488-
/**
489-
* Get the attribute flags (for attribute selectors: i, s)
490-
* Returns "i" (case-insensitive), "s" (case-sensitive), or null if no flag is present.
491-
* Derived from source text after the attribute value.
492-
*/
467+
/** Attribute selector flag: "i" (case-insensitive), "s" (case-sensitive), or null if absent. */
493468
get attr_flags(): string | null | undefined {
494469
if (this.type !== ATTRIBUTE_SELECTOR) return undefined
495470

@@ -684,11 +659,7 @@ export class CSSNode {
684659
return sibling_index !== 0
685660
}
686661

687-
/**
688-
* Check if this node has children
689-
* For pseudo-class/pseudo-element functions, returns true if FLAG_HAS_PARENS is set
690-
* This allows formatters to distinguish :lang() from :hover
691-
*/
662+
/** Whether this node has children. For pseudo-class/element functions, tracks FLAG_HAS_PARENS so formatters can tell `:lang()` from `:hover`. */
692663
get has_children(): boolean {
693664
let { type } = this
694665
// For pseudo-class/pseudo-element nodes, check if they have function syntax
@@ -795,13 +766,8 @@ export class CSSNode {
795766
// --- Node Cloning ---
796767

797768
/**
798-
* Clone this node as a mutable plain JavaScript object with children as arrays.
799-
* See API.md for examples.
800-
* Warning: this should be used sparingly because it potentially consumes a lot of memory.
801-
*
802-
* @param options - Cloning configuration
803-
* @param options.deep - Recursively clone children (default: true)
804-
* @param options.locations - Include line/column/start/length (default: false)
769+
* Clone this node as a mutable plain object with children as arrays.
770+
* Use sparingly — can consume a lot of memory.
805771
*/
806772
clone(options: CloneOptions = {}): PlainCSSNode {
807773
const { deep = true, locations = false } = options

src/node-types.ts

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,7 @@ type Leaf<Type extends CSSNodeType, Name extends TypeName, Extra = {}> = WithClo
110110
CSSNode & Extra & { readonly type: Type; readonly type_name: Name }
111111
>
112112

113-
/**
114-
* Mixin for node types that have child nodes.
115-
*
116-
* Only a subset of node types expose children — structural and container nodes
117-
* like StyleSheet, Block, SelectorList, Value, Function, etc. Leaf nodes
118-
* (Identifier, Number, Dimension, …) do not extend WithChildren, reflecting
119-
* that they never carry child nodes in a well-formed tree.
120-
*/
113+
/** Mixin for container node types (StyleSheet, Block, SelectorList, …). Leaf nodes never carry children, so they skip this. */
121114
export interface WithChildren<T = AnyNode> {
122115
readonly has_children: boolean
123116
readonly child_count: number
@@ -127,21 +120,10 @@ export interface WithChildren<T = AnyNode> {
127120
}
128121

129122
/**
130-
* Maps a CssNodeCommon subtype interface to its plain-object equivalent,
131-
* as returned by clone().
132-
*
133-
* The result is always a subtype of PlainCSSNode (the intersection starts
134-
* with PlainCSSNode), with two additions:
135-
* - `type` is narrowed to T's specific literal (enables discriminated unions)
136-
* - subtype-specific properties (those not on CssNodeCommon) are added with
137-
* CssNodeCommon references replaced by PlainCSSNode
138-
*
139-
* Traversal properties (first_child, next_sibling, etc.) are excluded since
140-
* they live on CssNodeCommon and are never serialised by clone().
141-
*
142-
* const rule = root.first_child as Rule
143-
* rule.clone().prelude // PlainCSSNode | null — not PlainCSSNode | undefined
144-
* rule.clone().block // PlainCSSNode | null
123+
* Maps a CssNodeCommon subtype to its clone() equivalent: `type` narrowed to
124+
* T's literal, subtype-specific fields with CssNodeCommon refs replaced by
125+
* PlainCSSNode, and traversal props (first_child, next_sibling, …) dropped
126+
* since clone() never serialises them.
145127
*/
146128
export type ToPlain<T extends CSSNode> = PlainCSSNode & { type: T['type'] } & {
147129
[K in Exclude<
@@ -232,12 +214,9 @@ export type SelectorList = WithClone<
232214
>
233215

234216
/**
235-
* A node that appears as a direct child of a Block.
236-
*
237-
* Identical to `Raw | Declaration | Atrule | Rule` except that `next_sibling`
238-
* is narrowed to the same union instead of the generic `CSSNode`. This is
239-
* safe because none of these four types use WithChildren themselves, so
240-
* there is no recursive type graph to trigger TS2589.
217+
* A direct child of a Block: `Raw | Declaration | Atrule | Rule` with
218+
* `next_sibling` narrowed to the same union instead of generic `CSSNode`.
219+
* Safe since none of the four use WithChildren, avoiding TS2589.
241220
*/
242221
export type BlockChild = (Raw | Declaration | Atrule | Rule) &
243222
Toggle<'has_next', 'next_sibling', Raw | Declaration | Atrule | Rule>
@@ -539,20 +518,10 @@ export type LayerName = Leaf<
539518
>
540519

541520
/**
542-
* A parenthesised selector argument in an at-rule prelude.
543-
*
544-
* This node type exists because at-rule preludes that contain selectors (like
545-
* @scope) cannot reuse SELECTOR_LIST: that type already appears inside the
546-
* rule's block, and mixing the two would make traversal ambiguous. A distinct
547-
* type lets walkers and tooling distinguish "this is a selector used as a
548-
* scoping argument" from "this is a selector that matches elements".
549-
*
550-
* Currently produced only by @scope:
551-
* @scope (.parent) to (.child) { }
552-
* ^^^^^^^^^ ^^^^^^^^ — each parenthesised group is a PRELUDE_SELECTORLIST
553-
*
554-
* `value` is the raw selector text inside the parentheses, trimmed of
555-
* whitespace: ".parent" from "(.parent)".
521+
* A parenthesised selector argument in an at-rule prelude, e.g. `(.parent)`
522+
* in `@scope (.parent) to (.child)`. Distinct from SELECTOR_LIST, which
523+
* already means "matches elements", so tooling can tell scoping arguments
524+
* apart from real selectors. `value` is the trimmed text inside the parens.
556525
*/
557526
export type PreludeSelectorList = Leaf<
558527
typeof PRELUDE_SELECTORLIST,

src/parse-dimension.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
import { is_digit, CHAR_MINUS_HYPHEN, CHAR_PLUS, CHAR_PERIOD } from './string-utils'
22

3-
/**
4-
* Parse a dimension string into numeric value and unit
5-
*
6-
* @param text - Dimension text like "100px", "50%", "1.5em"
7-
* @returns Object with value (number) and unit (string)
8-
*
9-
* Examples:
10-
* - "100px" → { value: 100, unit: "px" }
11-
* - "50%" → { value: 50, unit: "%" }
12-
* - "1.5em" → { value: 1.5, unit: "em" }
13-
* - "-10rem" → { value: -10, unit: "rem" }
14-
*/
3+
/** Parse a dimension string into value and unit, e.g. "100px" → { value: 100, unit: "px" } or "2%" → { value: 2, unit: "%" } */
154
export function parse_dimension(text: string): { value: number; unit: string } {
165
// Find where the numeric part ends
176
let num_end = 0

src/parse-utils.ts

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,14 @@
11
import { CHAR_ASTERISK, CHAR_FORWARD_SLASH, is_whitespace } from './string-utils'
22

3-
/**
4-
* Skip whitespace forward from a position
5-
*
6-
* @param source - The source string
7-
* @param pos - Starting position
8-
* @param end - End boundary (exclusive)
9-
* @returns New position after skipping whitespace
10-
* @internal
11-
*/
3+
/** @internal */
124
export function skip_whitespace_forward(source: string, pos: number, end: number): number {
135
while (pos < end && is_whitespace(source.charCodeAt(pos))) {
146
pos++
157
}
168
return pos
179
}
1810

19-
/**
20-
* Skip whitespace and comments forward from a position
21-
*
22-
* @param source - The source string
23-
* @param pos - Starting position
24-
* @param end - End boundary (exclusive)
25-
* @returns New position after skipping whitespace/comments
26-
* @internal
27-
*/
11+
/** @internal */
2812
export function skip_whitespace_and_comments_forward(
2913
source: string,
3014
pos: number,
@@ -65,15 +49,7 @@ export function skip_whitespace_and_comments_forward(
6549
return pos
6650
}
6751

68-
/**
69-
* Skip whitespace and comments backward from a position
70-
*
71-
* @param source - The source string
72-
* @param pos - Starting position (exclusive, scanning backward from pos-1)
73-
* @param start - Start boundary (inclusive, won't go before this)
74-
* @returns New position after skipping whitespace/comments backward
75-
* @internal
76-
*/
52+
/** @internal */
7753
export function skip_whitespace_and_comments_backward(
7854
source: string,
7955
pos: number,
@@ -111,17 +87,8 @@ export function skip_whitespace_and_comments_backward(
11187
}
11288

11389
/**
114-
* Trim whitespace and comments from both ends of a string range
115-
*
116-
* @param source - The source string
117-
* @param start - Start offset in source
118-
* @param end - End offset in source
119-
* @returns [trimmed_start, trimmed_end] or null if all whitespace/comments
90+
* Trims whitespace and CSS comments from both ends; returns null if the range is only whitespace/comments.
12091
* @internal
121-
*
122-
* Skips whitespace (space, tab, newline, CR, FF) and CSS comments from both ends
123-
* of the specified range. Returns the trimmed boundaries or null if the range
124-
* contains only whitespace and comments.
12592
*/
12693
export function trim_boundaries(
12794
source: string,

0 commit comments

Comments
 (0)