init claude-code
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import type { DOMElement } from './dom.js'
|
||||
import type { TextStyles } from './styles.js'
|
||||
|
||||
/**
|
||||
* A segment of text with its associated styles.
|
||||
* Used for structured rendering without ANSI string transforms.
|
||||
*/
|
||||
export type StyledSegment = {
|
||||
text: string
|
||||
styles: TextStyles
|
||||
hyperlink?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Squash text nodes into styled segments, propagating styles down through the tree.
|
||||
* This allows structured styling without relying on ANSI string transforms.
|
||||
*/
|
||||
export function squashTextNodesToSegments(
|
||||
node: DOMElement,
|
||||
inheritedStyles: TextStyles = {},
|
||||
inheritedHyperlink?: string,
|
||||
out: StyledSegment[] = [],
|
||||
): StyledSegment[] {
|
||||
const mergedStyles = node.textStyles
|
||||
? { ...inheritedStyles, ...node.textStyles }
|
||||
: inheritedStyles
|
||||
|
||||
for (const childNode of node.childNodes) {
|
||||
if (childNode === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (childNode.nodeName === '#text') {
|
||||
if (childNode.nodeValue.length > 0) {
|
||||
out.push({
|
||||
text: childNode.nodeValue,
|
||||
styles: mergedStyles,
|
||||
hyperlink: inheritedHyperlink,
|
||||
})
|
||||
}
|
||||
} else if (
|
||||
childNode.nodeName === 'ink-text' ||
|
||||
childNode.nodeName === 'ink-virtual-text'
|
||||
) {
|
||||
squashTextNodesToSegments(
|
||||
childNode,
|
||||
mergedStyles,
|
||||
inheritedHyperlink,
|
||||
out,
|
||||
)
|
||||
} else if (childNode.nodeName === 'ink-link') {
|
||||
const href = childNode.attributes['href'] as string | undefined
|
||||
squashTextNodesToSegments(
|
||||
childNode,
|
||||
mergedStyles,
|
||||
href || inheritedHyperlink,
|
||||
out,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
/**
|
||||
* Squash text nodes into a plain string (without styles).
|
||||
* Used for text measurement in layout calculations.
|
||||
*/
|
||||
function squashTextNodes(node: DOMElement): string {
|
||||
let text = ''
|
||||
|
||||
for (const childNode of node.childNodes) {
|
||||
if (childNode === undefined) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (childNode.nodeName === '#text') {
|
||||
text += childNode.nodeValue
|
||||
} else if (
|
||||
childNode.nodeName === 'ink-text' ||
|
||||
childNode.nodeName === 'ink-virtual-text'
|
||||
) {
|
||||
text += squashTextNodes(childNode)
|
||||
} else if (childNode.nodeName === 'ink-link') {
|
||||
text += squashTextNodes(childNode)
|
||||
}
|
||||
}
|
||||
|
||||
return text
|
||||
}
|
||||
|
||||
export default squashTextNodes
|
||||
Reference in New Issue
Block a user