@jrichman/ink 6.4.10 → 6.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/App.d.ts +6 -0
- package/build/components/App.js +5 -0
- package/build/components/App.js.map +1 -1
- package/build/components/AppContext.d.ts +36 -1
- package/build/components/AppContext.js +7 -2
- package/build/components/AppContext.js.map +1 -1
- package/build/components/Box.d.ts +26 -2
- package/build/components/Box.js +3 -2
- package/build/components/Box.js.map +1 -1
- package/build/components/StaticRender.d.ts +8 -0
- package/build/components/StaticRender.js +11 -0
- package/build/components/StaticRender.js.map +1 -0
- package/build/debug-log.d.ts +2 -0
- package/build/debug-log.js +44 -0
- package/build/debug-log.js.map +1 -0
- package/build/dom.d.ts +37 -3
- package/build/dom.js +19 -3
- package/build/dom.js.map +1 -1
- package/build/index.d.ts +4 -1
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/ink.d.ts +38 -2
- package/build/ink.js +223 -97
- package/build/ink.js.map +1 -1
- package/build/measure-element.d.ts +20 -1
- package/build/measure-element.js +201 -51
- package/build/measure-element.js.map +1 -1
- package/build/output.d.ts +195 -10
- package/build/output.js +494 -160
- package/build/output.js.map +1 -1
- package/build/reconciler.js +19 -3
- package/build/reconciler.js.map +1 -1
- package/build/render-background.js +1 -1
- package/build/render-background.js.map +1 -1
- package/build/render-cached.d.ts +17 -0
- package/build/render-cached.js +62 -0
- package/build/render-cached.js.map +1 -0
- package/build/render-container.d.ts +24 -0
- package/build/render-container.js +169 -0
- package/build/render-container.js.map +1 -0
- package/build/render-node-to-output.d.ts +15 -7
- package/build/render-node-to-output.js +123 -485
- package/build/render-node-to-output.js.map +1 -1
- package/build/render-screen-reader.d.ts +5 -0
- package/build/render-screen-reader.js +54 -0
- package/build/render-screen-reader.js.map +1 -0
- package/build/render-scrollbar.d.ts +22 -0
- package/build/render-scrollbar.js +77 -0
- package/build/render-scrollbar.js.map +1 -0
- package/build/render-sticky.d.ts +56 -0
- package/build/render-sticky.js +314 -0
- package/build/render-sticky.js.map +1 -0
- package/build/render-text-node.d.ts +24 -0
- package/build/render-text-node.js +133 -0
- package/build/render-text-node.js.map +1 -0
- package/build/render.d.ts +39 -0
- package/build/render.js +5 -0
- package/build/render.js.map +1 -1
- package/build/renderer.d.ts +10 -2
- package/build/renderer.js +103 -7
- package/build/renderer.js.map +1 -1
- package/build/replay.d.ts +60 -0
- package/build/replay.js +138 -0
- package/build/replay.js.map +1 -0
- package/build/scroll.js +20 -1
- package/build/scroll.js.map +1 -1
- package/build/selection.d.ts +9 -0
- package/build/selection.js +47 -0
- package/build/selection.js.map +1 -1
- package/build/serialization.d.ts +28 -0
- package/build/serialization.js +267 -0
- package/build/serialization.js.map +1 -0
- package/build/styles.d.ts +18 -0
- package/build/styles.js.map +1 -1
- package/build/terminal-buffer.d.ts +53 -0
- package/build/terminal-buffer.js +441 -0
- package/build/terminal-buffer.js.map +1 -0
- package/build/worker/animation-controller.d.ts +72 -0
- package/build/worker/animation-controller.js +128 -0
- package/build/worker/animation-controller.js.map +1 -0
- package/build/worker/ansi-utils.d.ts +16 -0
- package/build/worker/ansi-utils.js +40 -0
- package/build/worker/ansi-utils.js.map +1 -0
- package/build/worker/canvas.d.ts +47 -0
- package/build/worker/canvas.js +94 -0
- package/build/worker/canvas.js.map +1 -0
- package/build/worker/compositor.d.ts +33 -0
- package/build/worker/compositor.js +314 -0
- package/build/worker/compositor.js.map +1 -0
- package/build/worker/platform.d.ts +15 -0
- package/build/worker/platform.js +19 -0
- package/build/worker/platform.js.map +1 -0
- package/build/worker/render-worker.d.ts +112 -0
- package/build/worker/render-worker.js +936 -0
- package/build/worker/render-worker.js.map +1 -0
- package/build/worker/scene-manager.d.ts +26 -0
- package/build/worker/scene-manager.js +99 -0
- package/build/worker/scene-manager.js.map +1 -0
- package/build/worker/scroll-optimizer.d.ts +32 -0
- package/build/worker/scroll-optimizer.js +110 -0
- package/build/worker/scroll-optimizer.js.map +1 -0
- package/build/worker/terminal-writer.d.ts +116 -0
- package/build/worker/terminal-writer.js +722 -0
- package/build/worker/terminal-writer.js.map +1 -0
- package/build/worker/worker-entry.d.ts +6 -0
- package/build/worker/worker-entry.js +130 -0
- package/build/worker/worker-entry.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { isNodeSelectable } from './dom.js';
|
|
7
|
+
import { measureStyledChars, splitStyledCharsByNewline, toStyledCharacters, } from './measure-text.js';
|
|
8
|
+
import { wrapOrTruncateStyledChars } from './text-wrap.js';
|
|
9
|
+
import getMaxWidth from './get-max-width.js';
|
|
10
|
+
import squashTextNodes from './squash-text-nodes.js';
|
|
11
|
+
import { applySelectionToStyledChars } from './selection.js';
|
|
12
|
+
export const applyPaddingToStyledChars = (node, lines) => {
|
|
13
|
+
const yogaNode = node.childNodes[0]?.yogaNode;
|
|
14
|
+
if (yogaNode) {
|
|
15
|
+
const offsetX = yogaNode.getComputedLeft();
|
|
16
|
+
const offsetY = yogaNode.getComputedTop();
|
|
17
|
+
const space = {
|
|
18
|
+
type: 'char',
|
|
19
|
+
value: ' ',
|
|
20
|
+
fullWidth: false,
|
|
21
|
+
styles: [],
|
|
22
|
+
};
|
|
23
|
+
const paddingLeft = Array.from({ length: offsetX }).map(() => space);
|
|
24
|
+
lines = lines.map(line => [...paddingLeft, ...line]);
|
|
25
|
+
const paddingTop = Array.from({ length: offsetY }).map(() => []);
|
|
26
|
+
lines.unshift(...paddingTop);
|
|
27
|
+
}
|
|
28
|
+
return lines;
|
|
29
|
+
};
|
|
30
|
+
export const calculateWrappedCursorPosition = (lines, styledChars, targetOffset) => {
|
|
31
|
+
const styledCharToOffset = new Map();
|
|
32
|
+
let offset = 0;
|
|
33
|
+
for (const char of styledChars) {
|
|
34
|
+
styledCharToOffset.set(char, offset);
|
|
35
|
+
offset += char.value.length;
|
|
36
|
+
}
|
|
37
|
+
let cursorLineIndex = lines.length - 1;
|
|
38
|
+
let relativeCursorPosition = targetOffset;
|
|
39
|
+
// -1 represents "before document start" so first character (offset 0) is handled correctly
|
|
40
|
+
let previousLineEndOffset = -1;
|
|
41
|
+
for (const [i, line] of lines.entries()) {
|
|
42
|
+
if (line.length > 0) {
|
|
43
|
+
const firstChar = line.find(char => styledCharToOffset.has(char));
|
|
44
|
+
const lastChar = line.findLast(char => styledCharToOffset.has(char));
|
|
45
|
+
if (!firstChar || !lastChar) {
|
|
46
|
+
// Padding-only line (originally empty), treat as empty line
|
|
47
|
+
if (targetOffset > previousLineEndOffset) {
|
|
48
|
+
cursorLineIndex = i;
|
|
49
|
+
relativeCursorPosition = targetOffset - previousLineEndOffset - 1;
|
|
50
|
+
previousLineEndOffset++;
|
|
51
|
+
}
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const lineStartOffset = styledCharToOffset.get(firstChar);
|
|
55
|
+
const lineEndOffset = styledCharToOffset.get(lastChar) + lastChar.value.length;
|
|
56
|
+
// Set as candidate if targetOffset is at or after line start
|
|
57
|
+
if (targetOffset >= lineStartOffset) {
|
|
58
|
+
cursorLineIndex = i;
|
|
59
|
+
relativeCursorPosition = Math.max(0, targetOffset - lineStartOffset);
|
|
60
|
+
}
|
|
61
|
+
// Finalize and exit if targetOffset is within or before this line's range.
|
|
62
|
+
// If targetOffset is in a gap (between previousLineEndOffset and lineStartOffset),
|
|
63
|
+
// the cursor stays at the previous line's end (already set in previous iteration).
|
|
64
|
+
if (targetOffset <= lineEndOffset) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
previousLineEndOffset = lineEndOffset;
|
|
68
|
+
}
|
|
69
|
+
else if (i === 0 && targetOffset === 0) {
|
|
70
|
+
// Edge case: First line is empty and cursor is at position 0
|
|
71
|
+
cursorLineIndex = 0;
|
|
72
|
+
relativeCursorPosition = 0;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
else if (i > 0 && targetOffset > previousLineEndOffset) {
|
|
76
|
+
// Handle empty lines (usually caused by \n)
|
|
77
|
+
cursorLineIndex = i;
|
|
78
|
+
relativeCursorPosition = targetOffset - previousLineEndOffset - 1;
|
|
79
|
+
// Advance past the \n character
|
|
80
|
+
previousLineEndOffset++;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { cursorLineIndex, relativeCursorPosition };
|
|
84
|
+
};
|
|
85
|
+
export function handleTextNode(node, output, options) {
|
|
86
|
+
const { x, y, newTransformers, selectionMap, selectionStyle } = options;
|
|
87
|
+
const text = squashTextNodes(node);
|
|
88
|
+
let styledChars = toStyledCharacters(text);
|
|
89
|
+
let selectionState;
|
|
90
|
+
const selectionRange = selectionMap?.get(node);
|
|
91
|
+
if (selectionRange) {
|
|
92
|
+
selectionState = {
|
|
93
|
+
range: selectionRange,
|
|
94
|
+
currentOffset: 0,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (selectionState) {
|
|
98
|
+
styledChars = applySelectionToStyledChars(styledChars, selectionState, selectionStyle);
|
|
99
|
+
}
|
|
100
|
+
if (styledChars.length > 0 || node.internal_terminalCursorFocus) {
|
|
101
|
+
let lines = [];
|
|
102
|
+
let cursorLineIndex = 0;
|
|
103
|
+
let relativeCursorPosition = node.internal_terminalCursorPosition ?? 0;
|
|
104
|
+
if (styledChars.length > 0) {
|
|
105
|
+
const { width: currentWidth } = measureStyledChars(styledChars);
|
|
106
|
+
const maxWidth = getMaxWidth(node.yogaNode);
|
|
107
|
+
lines =
|
|
108
|
+
currentWidth > maxWidth
|
|
109
|
+
? wrapOrTruncateStyledChars(styledChars, maxWidth, node.style.textWrap ?? 'wrap')
|
|
110
|
+
: splitStyledCharsByNewline(styledChars);
|
|
111
|
+
lines = applyPaddingToStyledChars(node, lines);
|
|
112
|
+
cursorLineIndex = lines.length - 1;
|
|
113
|
+
if (node.internal_terminalCursorFocus &&
|
|
114
|
+
node.internal_terminalCursorPosition !== undefined) {
|
|
115
|
+
({ cursorLineIndex, relativeCursorPosition } =
|
|
116
|
+
calculateWrappedCursorPosition(lines, styledChars, node.internal_terminalCursorPosition));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
lines = [[]];
|
|
121
|
+
}
|
|
122
|
+
for (const [index, line] of lines.entries()) {
|
|
123
|
+
output.write(x, y + index, line, {
|
|
124
|
+
transformers: newTransformers,
|
|
125
|
+
lineIndex: index,
|
|
126
|
+
isTerminalCursorFocused: node.internal_terminalCursorFocus && index === cursorLineIndex,
|
|
127
|
+
terminalCursorPosition: relativeCursorPosition,
|
|
128
|
+
isSelectable: isNodeSelectable(node),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=render-text-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-text-node.js","sourceRoot":"","sources":["../src/render-text-node.ts"],"names":[],"mappings":"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"}
|
package/build/render.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ReactNode } from 'react';
|
|
|
2
2
|
import { type StyledChar } from '@alcalzone/ansi-tokenize';
|
|
3
3
|
import Ink, { type RenderMetrics } from './ink.js';
|
|
4
4
|
import { type Selection } from './selection.js';
|
|
5
|
+
import { type DOMElement } from './dom.js';
|
|
5
6
|
export type RenderOptions = {
|
|
6
7
|
/**
|
|
7
8
|
Output stream where app will be rendered.
|
|
@@ -89,6 +90,34 @@ export type RenderOptions = {
|
|
|
89
90
|
*/
|
|
90
91
|
selectionStyle?: (char: StyledChar) => StyledChar;
|
|
91
92
|
standardReactLayoutTiming?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Use a separate process-based rendering mode so that render updates are
|
|
95
|
+
* not blocked by the main thread
|
|
96
|
+
*
|
|
97
|
+
* @default false
|
|
98
|
+
*/
|
|
99
|
+
renderProcess?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Use the terminal buffer logic (backbuffer tracking) for rendering.
|
|
102
|
+
* If `renderProcess` is also true, this is implied.
|
|
103
|
+
* If `renderProcess` is false and this is true, the terminal buffer logic runs in the main process.
|
|
104
|
+
*
|
|
105
|
+
* @default false
|
|
106
|
+
*/
|
|
107
|
+
terminalBuffer?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* If true, the worker-based renderer will automatically scroll all scrollable regions
|
|
110
|
+
* by 1 line every 16ms. This is only supported when using `terminalBuffer` or `renderProcess`.
|
|
111
|
+
*
|
|
112
|
+
* @default false
|
|
113
|
+
*/
|
|
114
|
+
animatedScroll?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Render sticky headers stuck at the top/bottom of scrollable regions
|
|
117
|
+
* when they are pushed to the terminal backbuffer.
|
|
118
|
+
* @default false
|
|
119
|
+
*/
|
|
120
|
+
stickyHeadersInBackbuffer?: boolean;
|
|
92
121
|
};
|
|
93
122
|
export type Instance = {
|
|
94
123
|
/**
|
|
@@ -116,6 +145,16 @@ export type Instance = {
|
|
|
116
145
|
* Get the selection object.
|
|
117
146
|
*/
|
|
118
147
|
getSelection: () => Selection;
|
|
148
|
+
/**
|
|
149
|
+
* Exports the current internal rendering state to a JSON file and a human-readable text dump.
|
|
150
|
+
* Only supported when `terminalBuffer` is enabled.
|
|
151
|
+
* @param filename The path/name for the JSON file (e.g., 'snapshot.json').
|
|
152
|
+
*/
|
|
153
|
+
dumpCurrentFrame: (filename: string) => void;
|
|
154
|
+
/**
|
|
155
|
+
* Internal root node of the Ink tree.
|
|
156
|
+
*/
|
|
157
|
+
rootNode: DOMElement;
|
|
119
158
|
};
|
|
120
159
|
/**
|
|
121
160
|
Mount a component and render the output.
|
package/build/render.js
CHANGED
|
@@ -18,6 +18,9 @@ const render = (node, options) => {
|
|
|
18
18
|
alternateBufferAlreadyActive: false,
|
|
19
19
|
incrementalRendering: false,
|
|
20
20
|
standardReactLayoutTiming: false,
|
|
21
|
+
renderProcess: false,
|
|
22
|
+
terminalBuffer: false,
|
|
23
|
+
animatedScroll: false,
|
|
21
24
|
...getOptions(options),
|
|
22
25
|
};
|
|
23
26
|
const instance = getInstance(inkOptions.stdout, () => new Ink(inkOptions));
|
|
@@ -32,6 +35,8 @@ const render = (node, options) => {
|
|
|
32
35
|
clear: instance.clear,
|
|
33
36
|
recalculateLayout: instance.recalculateLayout,
|
|
34
37
|
getSelection: instance.getSelection,
|
|
38
|
+
dumpCurrentFrame: instance.dumpCurrentFrame,
|
|
39
|
+
rootNode: instance.rootNode,
|
|
35
40
|
};
|
|
36
41
|
};
|
|
37
42
|
export default render;
|
package/build/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,OAAO,MAAM,cAAc,CAAC;AAGnC,OAAO,GAAqD,MAAM,UAAU,CAAC;AAC7E,OAAO,SAAS,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACnC,OAAO,OAAO,MAAM,cAAc,CAAC;AAGnC,OAAO,GAAqD,MAAM,UAAU,CAAC;AAC7E,OAAO,SAAS,MAAM,gBAAgB,CAAC;AAgMvC;;EAEE;AACF,MAAM,MAAM,GAAG,CACd,IAAe,EACf,OAA4C,EACjC,EAAE;IACb,MAAM,UAAU,GAAe;QAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,EAAE;QACV,eAAe,EAAE,KAAK;QACtB,4BAA4B,EAAE,KAAK;QACnC,oBAAoB,EAAE,KAAK;QAC3B,yBAAyB,EAAE,KAAK;QAChC,aAAa,EAAE,KAAK;QACpB,cAAc,EAAE,KAAK;QACrB,cAAc,EAAE,KAAK;QACrB,GAAG,UAAU,CAAC,OAAO,CAAC;KACtB,CAAC;IAEF,MAAM,QAAQ,GAAQ,WAAW,CAChC,UAAU,CAAC,MAAM,EACjB,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CACzB,CAAC;IAEF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtB,OAAO;QACN,QAAQ,EAAE,QAAQ,CAAC,MAAM;QACzB,OAAO;YACN,QAAQ,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAClD,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB;QAC7C,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;QAC3C,QAAQ,EAAE,QAAQ,CAAC,QAAQ;KAC3B,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,MAAM,CAAC;AAEtB,MAAM,UAAU,GAAG,CAClB,SAAyD,EAAE,EAC3C,EAAE;IAClB,IAAI,MAAM,YAAY,MAAM,EAAE,CAAC;QAC9B,OAAO;YACN,MAAM;YACN,KAAK,EAAE,OAAO,CAAC,KAAK;SACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CACnB,MAA0B,EAC1B,cAAyB,EACnB,EAAE;IACR,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAErC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,QAAQ,GAAG,cAAc,EAAE,CAAC;QAC5B,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC,CAAC"}
|
package/build/renderer.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type StyledChar } from '@alcalzone/ansi-tokenize';
|
|
2
|
-
import { type
|
|
2
|
+
import { type Region } from './output.js';
|
|
3
|
+
import { type DOMElement, type StickyHeader } from './dom.js';
|
|
3
4
|
import { type Selection } from './selection.js';
|
|
4
5
|
type Result = {
|
|
5
6
|
output: string;
|
|
@@ -10,6 +11,13 @@ type Result = {
|
|
|
10
11
|
row: number;
|
|
11
12
|
col: number;
|
|
12
13
|
};
|
|
14
|
+
stickyHeaders: StickyHeader[];
|
|
15
|
+
root?: Region;
|
|
13
16
|
};
|
|
14
|
-
declare const renderer: (node: DOMElement,
|
|
17
|
+
declare const renderer: (node: DOMElement, options: {
|
|
18
|
+
isScreenReaderEnabled: boolean;
|
|
19
|
+
selection?: Selection;
|
|
20
|
+
selectionStyle?: (char: StyledChar) => StyledChar;
|
|
21
|
+
skipScrollbars?: boolean;
|
|
22
|
+
}) => Result;
|
|
15
23
|
export default renderer;
|
package/build/renderer.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
1
|
+
import { styledCharsToString } from '@alcalzone/ansi-tokenize';
|
|
2
|
+
import renderNodeToOutput from './render-node-to-output.js';
|
|
3
|
+
import { renderNodeToScreenReaderOutput } from './render-screen-reader.js';
|
|
4
|
+
import Output, { flattenRegion, clampCursorColumn, } from './output.js';
|
|
5
|
+
import { isNodeSelectable, } from './dom.js';
|
|
4
6
|
const calculateSelectionMap = (root, selection) => {
|
|
5
7
|
const map = new Map();
|
|
6
8
|
if (selection.rangeCount === 0) {
|
|
@@ -99,6 +101,53 @@ const calculateSelectionMap = (root, selection) => {
|
|
|
99
101
|
hasFoundEnd = true;
|
|
100
102
|
}
|
|
101
103
|
}
|
|
104
|
+
else if (node.nodeName === 'ink-static-render') {
|
|
105
|
+
if (!isNodeSelectable(node)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
// For StaticRender, the node itself is returned by hitTest and behaves like a text node.
|
|
109
|
+
// However, if the user clicked inside it, startContainer or endContainer might be this node itself,
|
|
110
|
+
// or it could be spanned by a selection outside it.
|
|
111
|
+
const localLength = node.cachedRender?.selectableText?.length ?? 0;
|
|
112
|
+
let nodeStartIndex = -1;
|
|
113
|
+
let nodeEndIndex = -1;
|
|
114
|
+
let foundStartInNode = false;
|
|
115
|
+
let foundEndInNode = false;
|
|
116
|
+
if (startContainer === node) {
|
|
117
|
+
foundStartInNode = true;
|
|
118
|
+
nodeStartIndex = startOffset;
|
|
119
|
+
}
|
|
120
|
+
if (endContainer === node) {
|
|
121
|
+
foundEndInNode = true;
|
|
122
|
+
nodeEndIndex = endOffset;
|
|
123
|
+
}
|
|
124
|
+
// Also check if its parent contains it as start/end, though hitTest usually sets the node itself
|
|
125
|
+
if (node.parentNode) {
|
|
126
|
+
const index = node.parentNode.childNodes.indexOf(node);
|
|
127
|
+
if (startContainer === node.parentNode && startOffset === index) {
|
|
128
|
+
foundStartInNode = true;
|
|
129
|
+
nodeStartIndex = 0;
|
|
130
|
+
}
|
|
131
|
+
if (endContainer === node.parentNode && endOffset === index + 1) {
|
|
132
|
+
foundEndInNode = true;
|
|
133
|
+
nodeEndIndex = localLength;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if ((hasFoundStart || foundStartInNode) &&
|
|
137
|
+
(!hasFoundEnd || foundEndInNode)) {
|
|
138
|
+
const start = foundStartInNode ? nodeStartIndex : 0;
|
|
139
|
+
const end = foundEndInNode ? nodeEndIndex : localLength;
|
|
140
|
+
if (start !== -1 && end !== -1 && start < end) {
|
|
141
|
+
map.set(node, { start, end });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (foundStartInNode) {
|
|
145
|
+
hasFoundStart = true;
|
|
146
|
+
}
|
|
147
|
+
if (foundEndInNode) {
|
|
148
|
+
hasFoundEnd = true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
102
151
|
else {
|
|
103
152
|
const { childNodes } = node;
|
|
104
153
|
if (childNodes) {
|
|
@@ -125,7 +174,19 @@ const calculateSelectionMap = (root, selection) => {
|
|
|
125
174
|
visit(root);
|
|
126
175
|
return map;
|
|
127
176
|
};
|
|
128
|
-
const renderer = (node,
|
|
177
|
+
const renderer = (node, options) => {
|
|
178
|
+
const { isScreenReaderEnabled, selection, selectionStyle, skipScrollbars } = options;
|
|
179
|
+
const callBeforeRender = (n) => {
|
|
180
|
+
if (typeof n.internalOnBeforeRender === 'function') {
|
|
181
|
+
n.internalOnBeforeRender(n);
|
|
182
|
+
}
|
|
183
|
+
for (const child of n.childNodes) {
|
|
184
|
+
if (child.nodeName !== '#text') {
|
|
185
|
+
callBeforeRender(child);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
callBeforeRender(node);
|
|
129
190
|
if (node.yogaNode) {
|
|
130
191
|
if (isScreenReaderEnabled) {
|
|
131
192
|
const output = renderNodeToScreenReaderOutput(node, {
|
|
@@ -143,11 +204,13 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
|
|
|
143
204
|
outputHeight,
|
|
144
205
|
staticOutput: staticOutput ? `${staticOutput}\n` : '',
|
|
145
206
|
styledOutput: [],
|
|
207
|
+
stickyHeaders: [],
|
|
146
208
|
};
|
|
147
209
|
}
|
|
148
210
|
const output = new Output({
|
|
149
211
|
width: node.yogaNode.getComputedWidth(),
|
|
150
212
|
height: node.yogaNode.getComputedHeight(),
|
|
213
|
+
node,
|
|
151
214
|
});
|
|
152
215
|
const selectionMap = selection
|
|
153
216
|
? calculateSelectionMap(node, selection)
|
|
@@ -162,6 +225,8 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
|
|
|
162
225
|
staticOutput = new Output({
|
|
163
226
|
width: node.staticNode.yogaNode.getComputedWidth(),
|
|
164
227
|
height: node.staticNode.yogaNode.getComputedHeight(),
|
|
228
|
+
node: node.staticNode,
|
|
229
|
+
id: node.staticNode.internalId,
|
|
165
230
|
});
|
|
166
231
|
renderNodeToOutput(node.staticNode, staticOutput, {
|
|
167
232
|
skipStaticElements: false,
|
|
@@ -171,15 +236,20 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
|
|
|
171
236
|
: undefined,
|
|
172
237
|
});
|
|
173
238
|
}
|
|
174
|
-
const
|
|
239
|
+
const rootRegion = output.get();
|
|
240
|
+
const { output: generatedOutput, height: outputHeight, styledOutput, cursorPosition, } = regionToOutput(rootRegion, { skipScrollbars });
|
|
175
241
|
return {
|
|
176
242
|
output: generatedOutput,
|
|
177
243
|
outputHeight,
|
|
178
244
|
// Newline at the end is needed, because static output doesn't have one, so
|
|
179
|
-
// interactive output will override last line of static output
|
|
180
|
-
staticOutput: staticOutput
|
|
245
|
+
// interactive output will override last line of static output.
|
|
246
|
+
staticOutput: staticOutput
|
|
247
|
+
? `${regionToOutput(staticOutput.get()).output}\n`
|
|
248
|
+
: '',
|
|
181
249
|
styledOutput,
|
|
182
250
|
cursorPosition,
|
|
251
|
+
stickyHeaders: [],
|
|
252
|
+
root: rootRegion,
|
|
183
253
|
};
|
|
184
254
|
}
|
|
185
255
|
return {
|
|
@@ -187,7 +257,33 @@ const renderer = (node, isScreenReaderEnabled, selection, selectionStyle) => {
|
|
|
187
257
|
outputHeight: 0,
|
|
188
258
|
staticOutput: '',
|
|
189
259
|
styledOutput: [],
|
|
260
|
+
stickyHeaders: [],
|
|
261
|
+
root: undefined,
|
|
190
262
|
};
|
|
191
263
|
};
|
|
264
|
+
function regionToOutput(region, options) {
|
|
265
|
+
const context = {};
|
|
266
|
+
const lines = flattenRegion(region, { context, ...options });
|
|
267
|
+
if (context.cursorPosition) {
|
|
268
|
+
const { row, col } = context.cursorPosition;
|
|
269
|
+
const line = lines[row];
|
|
270
|
+
if (line) {
|
|
271
|
+
context.cursorPosition.col = clampCursorColumn(line, col);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Flatten the root region for legacy string output
|
|
275
|
+
const generatedOutput = lines
|
|
276
|
+
.map(line => {
|
|
277
|
+
const lineWithoutEmptyItems = line.filter(item => item !== undefined);
|
|
278
|
+
return styledCharsToString(lineWithoutEmptyItems).trimEnd();
|
|
279
|
+
})
|
|
280
|
+
.join('\n');
|
|
281
|
+
return {
|
|
282
|
+
output: generatedOutput,
|
|
283
|
+
height: lines.length,
|
|
284
|
+
styledOutput: lines,
|
|
285
|
+
cursorPosition: context.cursorPosition,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
192
288
|
export default renderer;
|
|
193
289
|
//# sourceMappingURL=renderer.js.map
|
package/build/renderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { type RegionNode, type RegionUpdate } from './output.js';
|
|
7
|
+
import { type Serializer } from './serialization.js';
|
|
8
|
+
import { type StickyHeader } from './dom.js';
|
|
9
|
+
export type ReplayData = {
|
|
10
|
+
type: 'single' | 'sequence';
|
|
11
|
+
columns: number;
|
|
12
|
+
rows: number;
|
|
13
|
+
frames: ReplayFrame[];
|
|
14
|
+
};
|
|
15
|
+
export type ReplayFrame = {
|
|
16
|
+
tree: RegionNode;
|
|
17
|
+
updates: ReplayRegionUpdate[];
|
|
18
|
+
cursorPosition?: {
|
|
19
|
+
row: number;
|
|
20
|
+
col: number;
|
|
21
|
+
};
|
|
22
|
+
timestamp: number;
|
|
23
|
+
};
|
|
24
|
+
export type ReplayRegionUpdate = Omit<RegionUpdate, 'lines' | 'stickyHeaders'> & {
|
|
25
|
+
lines?: {
|
|
26
|
+
updates: Array<{
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
data: string;
|
|
30
|
+
source?: string;
|
|
31
|
+
}>;
|
|
32
|
+
totalLength: number;
|
|
33
|
+
};
|
|
34
|
+
stickyHeaders?: ReplayStickyHeader[];
|
|
35
|
+
};
|
|
36
|
+
export type ReplayStickyHeader = Omit<StickyHeader, 'node' | 'anchor' | 'lines' | 'stuckLines' | 'styledOutput'> & {
|
|
37
|
+
lines: string;
|
|
38
|
+
stuckLines?: string;
|
|
39
|
+
styledOutput: string;
|
|
40
|
+
};
|
|
41
|
+
export declare function serializeReplayUpdate(update: RegionUpdate, serializer: Serializer): ReplayRegionUpdate;
|
|
42
|
+
export declare function deserializeReplayUpdate(update: ReplayRegionUpdate): RegionUpdate;
|
|
43
|
+
export declare function saveReplay(data: ReplayData, filename: string): void;
|
|
44
|
+
export type LoadedReplayData = {
|
|
45
|
+
type: 'single' | 'sequence';
|
|
46
|
+
columns: number;
|
|
47
|
+
rows: number;
|
|
48
|
+
frames: LoadedReplayFrame[];
|
|
49
|
+
};
|
|
50
|
+
export type LoadedReplayFrame = {
|
|
51
|
+
tree: RegionNode;
|
|
52
|
+
updates: RegionUpdate[];
|
|
53
|
+
cursorPosition?: {
|
|
54
|
+
row: number;
|
|
55
|
+
col: number;
|
|
56
|
+
};
|
|
57
|
+
timestamp: number;
|
|
58
|
+
};
|
|
59
|
+
export declare function loadReplay(jsonStr: string): LoadedReplayData;
|
|
60
|
+
export declare function createHumanReadableDump(data: LoadedReplayData): string;
|
package/build/replay.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import { Buffer } from 'node:buffer';
|
|
8
|
+
import { Deserializer } from './serialization.js';
|
|
9
|
+
export function serializeReplayUpdate(update, serializer) {
|
|
10
|
+
const { lines, stickyHeaders, ...rest } = update;
|
|
11
|
+
const result = {
|
|
12
|
+
...rest,
|
|
13
|
+
};
|
|
14
|
+
if (lines) {
|
|
15
|
+
result.lines = {
|
|
16
|
+
totalLength: lines.totalLength,
|
|
17
|
+
updates: lines.updates.map(u => ({
|
|
18
|
+
start: u.start,
|
|
19
|
+
end: u.end,
|
|
20
|
+
data: Buffer.from(u.data).toString('base64'),
|
|
21
|
+
source: u.source ? Buffer.from(u.source).toString('base64') : undefined,
|
|
22
|
+
})),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (stickyHeaders) {
|
|
26
|
+
result.stickyHeaders = stickyHeaders.map(h => ({
|
|
27
|
+
...h,
|
|
28
|
+
node: undefined,
|
|
29
|
+
lines: Buffer.from(serializer.serialize(h.lines ?? [])).toString('base64'),
|
|
30
|
+
stuckLines: h.stuckLines
|
|
31
|
+
? Buffer.from(serializer.serialize(h.stuckLines)).toString('base64')
|
|
32
|
+
: undefined,
|
|
33
|
+
styledOutput: Buffer.from(serializer.serialize(h.styledOutput ?? [])).toString('base64'),
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
export function deserializeReplayUpdate(update) {
|
|
39
|
+
const { lines, stickyHeaders, ...rest } = update;
|
|
40
|
+
const result = {
|
|
41
|
+
...rest,
|
|
42
|
+
};
|
|
43
|
+
if (lines) {
|
|
44
|
+
result.lines = {
|
|
45
|
+
totalLength: lines.totalLength,
|
|
46
|
+
updates: lines.updates.map(u => ({
|
|
47
|
+
start: u.start,
|
|
48
|
+
end: u.end,
|
|
49
|
+
data: Buffer.from(u.data, 'base64'),
|
|
50
|
+
source: u.source ? Buffer.from(u.source, 'base64') : undefined,
|
|
51
|
+
})),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (stickyHeaders) {
|
|
55
|
+
result.stickyHeaders = stickyHeaders.map(h => {
|
|
56
|
+
const header = {
|
|
57
|
+
...h,
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
59
|
+
node: undefined,
|
|
60
|
+
lines: new Deserializer(Buffer.from(h.lines, 'base64')).deserialize(),
|
|
61
|
+
stuckLines: h.stuckLines
|
|
62
|
+
? new Deserializer(Buffer.from(h.stuckLines, 'base64')).deserialize()
|
|
63
|
+
: undefined,
|
|
64
|
+
styledOutput: new Deserializer(Buffer.from(h.styledOutput, 'base64')).deserialize(),
|
|
65
|
+
};
|
|
66
|
+
return header;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
export function saveReplay(data, filename) {
|
|
72
|
+
fs.writeFileSync(filename, JSON.stringify(data, null, 2));
|
|
73
|
+
}
|
|
74
|
+
export function loadReplay(jsonStr) {
|
|
75
|
+
const raw = JSON.parse(jsonStr);
|
|
76
|
+
return {
|
|
77
|
+
...raw,
|
|
78
|
+
frames: raw.frames.map(f => ({
|
|
79
|
+
...f,
|
|
80
|
+
updates: f.updates.map(u => deserializeReplayUpdate(u)),
|
|
81
|
+
})),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export function createHumanReadableDump(data) {
|
|
85
|
+
const dumpData = {
|
|
86
|
+
type: data.type,
|
|
87
|
+
columns: data.columns,
|
|
88
|
+
rows: data.rows,
|
|
89
|
+
frames: data.frames.map(frame => ({
|
|
90
|
+
tree: frame.tree,
|
|
91
|
+
cursorPosition: frame.cursorPosition,
|
|
92
|
+
updates: frame.updates.map(update => {
|
|
93
|
+
const dumpUpdate = { ...update };
|
|
94
|
+
// Explicitly copy properties that could be undefined if omitted in object spread occasionally
|
|
95
|
+
dumpUpdate['overflowToBackbuffer'] = update.overflowToBackbuffer;
|
|
96
|
+
dumpUpdate['isScrollable'] = update.isScrollable;
|
|
97
|
+
if (update.lines) {
|
|
98
|
+
dumpUpdate['lines'] = {
|
|
99
|
+
totalLength: update.lines.totalLength,
|
|
100
|
+
updates: update.lines.updates.map(u => {
|
|
101
|
+
const deserializer = new Deserializer(Buffer.from(u.data));
|
|
102
|
+
const lines = deserializer.deserialize();
|
|
103
|
+
return {
|
|
104
|
+
start: u.start,
|
|
105
|
+
end: u.end,
|
|
106
|
+
text: lines.map(line => line
|
|
107
|
+
.map(c => c.value)
|
|
108
|
+
.join('')
|
|
109
|
+
.trimEnd()),
|
|
110
|
+
};
|
|
111
|
+
}),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (update.stickyHeaders) {
|
|
115
|
+
dumpUpdate['stickyHeaders'] = update.stickyHeaders.map(h => ({
|
|
116
|
+
...h,
|
|
117
|
+
lines: (h.lines ?? []).map(line => line
|
|
118
|
+
.map(c => c.value)
|
|
119
|
+
.join('')
|
|
120
|
+
.trimEnd()),
|
|
121
|
+
stuckLines: h.stuckLines?.map(line => line
|
|
122
|
+
.map(c => c.value)
|
|
123
|
+
.join('')
|
|
124
|
+
.trimEnd()),
|
|
125
|
+
styledOutput: (h.styledOutput ?? []).map(line => line
|
|
126
|
+
.map(c => c.value)
|
|
127
|
+
.join('')
|
|
128
|
+
.trimEnd()),
|
|
129
|
+
node: undefined,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
return dumpUpdate;
|
|
133
|
+
}),
|
|
134
|
+
})),
|
|
135
|
+
};
|
|
136
|
+
return JSON.stringify(dumpData, null, 2);
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=replay.js.map
|