@next_term/web 0.1.0-next.0
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/dist/accessibility.d.ts +46 -0
- package/dist/accessibility.d.ts.map +1 -0
- package/dist/accessibility.js +196 -0
- package/dist/accessibility.js.map +1 -0
- package/dist/addon.d.ts.map +1 -0
- package/dist/addon.js +2 -0
- package/dist/addon.js.map +1 -0
- package/dist/addons/fit.d.ts.map +1 -0
- package/dist/addons/fit.js +40 -0
- package/dist/addons/fit.js.map +1 -0
- package/dist/addons/search.d.ts +56 -0
- package/dist/addons/search.d.ts.map +1 -0
- package/dist/addons/search.js +178 -0
- package/dist/addons/search.js.map +1 -0
- package/dist/addons/web-links.d.ts +30 -0
- package/dist/addons/web-links.d.ts.map +1 -0
- package/dist/addons/web-links.js +170 -0
- package/dist/addons/web-links.js.map +1 -0
- package/dist/fit.d.ts.map +1 -0
- package/dist/fit.js +14 -0
- package/dist/fit.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/input-handler.d.ts +185 -0
- package/dist/input-handler.d.ts.map +1 -0
- package/dist/input-handler.js +1197 -0
- package/dist/input-handler.js.map +1 -0
- package/dist/parser-worker.d.ts.map +1 -0
- package/dist/parser-worker.js +128 -0
- package/dist/parser-worker.js.map +1 -0
- package/dist/render-bridge.d.ts +56 -0
- package/dist/render-bridge.d.ts.map +1 -0
- package/dist/render-bridge.js +158 -0
- package/dist/render-bridge.js.map +1 -0
- package/dist/render-worker.d.ts +62 -0
- package/dist/render-worker.d.ts.map +1 -0
- package/dist/render-worker.js +720 -0
- package/dist/render-worker.js.map +1 -0
- package/dist/renderer.d.ts +86 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +454 -0
- package/dist/renderer.js.map +1 -0
- package/dist/shared-context.d.ts +93 -0
- package/dist/shared-context.d.ts.map +1 -0
- package/dist/shared-context.js +561 -0
- package/dist/shared-context.js.map +1 -0
- package/dist/web-terminal.d.ts +152 -0
- package/dist/web-terminal.d.ts.map +1 -0
- package/dist/web-terminal.js +684 -0
- package/dist/web-terminal.js.map +1 -0
- package/dist/webgl-renderer.d.ts +146 -0
- package/dist/webgl-renderer.d.ts.map +1 -0
- package/dist/webgl-renderer.js +1047 -0
- package/dist/webgl-renderer.js.map +1 -0
- package/dist/worker-bridge.d.ts +51 -0
- package/dist/worker-bridge.d.ts.map +1 -0
- package/dist/worker-bridge.js +185 -0
- package/dist/worker-bridge.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AccessibilityManager — parallel DOM approach for screen reader support.
|
|
3
|
+
*
|
|
4
|
+
* Creates an off-screen (but not display:none) container with an ARIA grid
|
|
5
|
+
* that mirrors the terminal's CellGrid content. Updates are throttled to
|
|
6
|
+
* 10 Hz to avoid excessive CPU usage.
|
|
7
|
+
*
|
|
8
|
+
* Inspired by the xterm.js accessibility approach.
|
|
9
|
+
*/
|
|
10
|
+
import type { CellGrid } from "@next_term/core";
|
|
11
|
+
/**
|
|
12
|
+
* Extract a single row's text content from a CellGrid.
|
|
13
|
+
* Trims trailing whitespace for cleaner screen reader output.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractRowText(grid: CellGrid, row: number): string;
|
|
16
|
+
export declare class AccessibilityManager {
|
|
17
|
+
private liveRegion;
|
|
18
|
+
private treeContainer;
|
|
19
|
+
private rowElements;
|
|
20
|
+
private grid;
|
|
21
|
+
private rows;
|
|
22
|
+
private cols;
|
|
23
|
+
private container;
|
|
24
|
+
private disposed;
|
|
25
|
+
/** Throttle interval in milliseconds (10 Hz). */
|
|
26
|
+
private static readonly THROTTLE_MS;
|
|
27
|
+
private throttleTimer;
|
|
28
|
+
private updateScheduled;
|
|
29
|
+
constructor(container: HTMLElement, grid: CellGrid, rows: number, cols: number);
|
|
30
|
+
/**
|
|
31
|
+
* Update the accessibility tree for dirty rows.
|
|
32
|
+
* Throttled to 10 Hz — safe to call on every render frame.
|
|
33
|
+
*/
|
|
34
|
+
update(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Announce text to screen readers via the live region.
|
|
37
|
+
*/
|
|
38
|
+
announce(text: string, priority?: "polite" | "assertive"): void;
|
|
39
|
+
/**
|
|
40
|
+
* Replace the grid reference (e.g. after resize).
|
|
41
|
+
*/
|
|
42
|
+
setGrid(grid: CellGrid, rows: number, cols: number): void;
|
|
43
|
+
dispose(): void;
|
|
44
|
+
private performUpdate;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=accessibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility.d.ts","sourceRoot":"","sources":["../src/accessibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAMhD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQlE;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAS;IAEzB,iDAAiD;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAO;IAE1C,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,eAAe,CAAS;gBAEpB,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IA+D9E;;;OAGG;IACH,MAAM,IAAI,IAAI;IAoBd;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAQ,GAAG,WAAsB,GAAG,IAAI;IAgBzE;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwBzD,OAAO,IAAI,IAAI;IAuBf,OAAO,CAAC,aAAa;CAatB"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AccessibilityManager — parallel DOM approach for screen reader support.
|
|
3
|
+
*
|
|
4
|
+
* Creates an off-screen (but not display:none) container with an ARIA grid
|
|
5
|
+
* that mirrors the terminal's CellGrid content. Updates are throttled to
|
|
6
|
+
* 10 Hz to avoid excessive CPU usage.
|
|
7
|
+
*
|
|
8
|
+
* Inspired by the xterm.js accessibility approach.
|
|
9
|
+
*/
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Helpers
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
/**
|
|
14
|
+
* Extract a single row's text content from a CellGrid.
|
|
15
|
+
* Trims trailing whitespace for cleaner screen reader output.
|
|
16
|
+
*/
|
|
17
|
+
export function extractRowText(grid, row) {
|
|
18
|
+
const cols = grid.cols;
|
|
19
|
+
let text = "";
|
|
20
|
+
for (let col = 0; col < cols; col++) {
|
|
21
|
+
const cp = grid.getCodepoint(row, col);
|
|
22
|
+
text += cp > 0x20 ? String.fromCodePoint(cp) : " ";
|
|
23
|
+
}
|
|
24
|
+
return text.replace(/\s+$/, "");
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// AccessibilityManager
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
export class AccessibilityManager {
|
|
30
|
+
liveRegion;
|
|
31
|
+
treeContainer;
|
|
32
|
+
rowElements;
|
|
33
|
+
grid;
|
|
34
|
+
rows;
|
|
35
|
+
cols;
|
|
36
|
+
container;
|
|
37
|
+
disposed = false;
|
|
38
|
+
/** Throttle interval in milliseconds (10 Hz). */
|
|
39
|
+
static THROTTLE_MS = 100;
|
|
40
|
+
throttleTimer = null;
|
|
41
|
+
updateScheduled = false;
|
|
42
|
+
constructor(container, grid, rows, cols) {
|
|
43
|
+
this.grid = grid;
|
|
44
|
+
this.rows = rows;
|
|
45
|
+
this.cols = cols;
|
|
46
|
+
this.container = container;
|
|
47
|
+
// Create the off-screen accessibility tree container.
|
|
48
|
+
// It is positioned absolutely, transparent, and ignores pointer events
|
|
49
|
+
// so it does not interfere with the canvas rendering.
|
|
50
|
+
this.treeContainer = document.createElement("div");
|
|
51
|
+
this.treeContainer.setAttribute("role", "grid");
|
|
52
|
+
this.treeContainer.setAttribute("aria-label", "Terminal output");
|
|
53
|
+
this.treeContainer.setAttribute("aria-readonly", "true");
|
|
54
|
+
Object.assign(this.treeContainer.style, {
|
|
55
|
+
position: "absolute",
|
|
56
|
+
top: "0",
|
|
57
|
+
left: "0",
|
|
58
|
+
width: "1px",
|
|
59
|
+
height: "1px",
|
|
60
|
+
overflow: "hidden",
|
|
61
|
+
opacity: "0",
|
|
62
|
+
pointerEvents: "none",
|
|
63
|
+
// clip-rect keeps it off-screen for sighted users while remaining
|
|
64
|
+
// accessible to screen readers (unlike display:none).
|
|
65
|
+
clip: "rect(0 0 0 0)",
|
|
66
|
+
clipPath: "inset(50%)",
|
|
67
|
+
whiteSpace: "nowrap",
|
|
68
|
+
});
|
|
69
|
+
// Build initial row elements
|
|
70
|
+
this.rowElements = [];
|
|
71
|
+
for (let r = 0; r < rows; r++) {
|
|
72
|
+
const rowEl = document.createElement("div");
|
|
73
|
+
rowEl.setAttribute("role", "row");
|
|
74
|
+
rowEl.setAttribute("aria-posinset", String(r + 1));
|
|
75
|
+
rowEl.setAttribute("aria-setsize", String(rows));
|
|
76
|
+
this.treeContainer.appendChild(rowEl);
|
|
77
|
+
this.rowElements.push(rowEl);
|
|
78
|
+
}
|
|
79
|
+
container.appendChild(this.treeContainer);
|
|
80
|
+
// Create live region for announcements (e.g. bell, output chunks)
|
|
81
|
+
this.liveRegion = document.createElement("div");
|
|
82
|
+
this.liveRegion.setAttribute("role", "log");
|
|
83
|
+
this.liveRegion.setAttribute("aria-live", "polite");
|
|
84
|
+
this.liveRegion.setAttribute("aria-relevant", "additions");
|
|
85
|
+
Object.assign(this.liveRegion.style, {
|
|
86
|
+
position: "absolute",
|
|
87
|
+
top: "0",
|
|
88
|
+
left: "0",
|
|
89
|
+
width: "1px",
|
|
90
|
+
height: "1px",
|
|
91
|
+
overflow: "hidden",
|
|
92
|
+
opacity: "0",
|
|
93
|
+
pointerEvents: "none",
|
|
94
|
+
clip: "rect(0 0 0 0)",
|
|
95
|
+
clipPath: "inset(50%)",
|
|
96
|
+
whiteSpace: "nowrap",
|
|
97
|
+
});
|
|
98
|
+
container.appendChild(this.liveRegion);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Update the accessibility tree for dirty rows.
|
|
102
|
+
* Throttled to 10 Hz — safe to call on every render frame.
|
|
103
|
+
*/
|
|
104
|
+
update() {
|
|
105
|
+
if (this.disposed)
|
|
106
|
+
return;
|
|
107
|
+
if (this.throttleTimer !== null) {
|
|
108
|
+
// An update is already scheduled; just mark that another one is wanted.
|
|
109
|
+
this.updateScheduled = true;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.performUpdate();
|
|
113
|
+
this.throttleTimer = setTimeout(() => {
|
|
114
|
+
this.throttleTimer = null;
|
|
115
|
+
if (this.updateScheduled) {
|
|
116
|
+
this.updateScheduled = false;
|
|
117
|
+
this.update();
|
|
118
|
+
}
|
|
119
|
+
}, AccessibilityManager.THROTTLE_MS);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Announce text to screen readers via the live region.
|
|
123
|
+
*/
|
|
124
|
+
announce(text, priority = "polite") {
|
|
125
|
+
if (this.disposed)
|
|
126
|
+
return;
|
|
127
|
+
this.liveRegion.setAttribute("aria-live", priority);
|
|
128
|
+
const span = document.createElement("span");
|
|
129
|
+
span.textContent = text;
|
|
130
|
+
this.liveRegion.appendChild(span);
|
|
131
|
+
// Keep the live region from growing unboundedly.
|
|
132
|
+
while (this.liveRegion.childNodes.length > 20) {
|
|
133
|
+
const first = this.liveRegion.firstChild;
|
|
134
|
+
if (first)
|
|
135
|
+
this.liveRegion.removeChild(first);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Replace the grid reference (e.g. after resize).
|
|
140
|
+
*/
|
|
141
|
+
setGrid(grid, rows, cols) {
|
|
142
|
+
this.grid = grid;
|
|
143
|
+
this.rows = rows;
|
|
144
|
+
this.cols = cols;
|
|
145
|
+
// Rebuild row elements if the count changed
|
|
146
|
+
while (this.rowElements.length > rows) {
|
|
147
|
+
const el = this.rowElements.pop();
|
|
148
|
+
if (el)
|
|
149
|
+
this.treeContainer.removeChild(el);
|
|
150
|
+
}
|
|
151
|
+
while (this.rowElements.length < rows) {
|
|
152
|
+
const rowEl = document.createElement("div");
|
|
153
|
+
rowEl.setAttribute("role", "row");
|
|
154
|
+
this.treeContainer.appendChild(rowEl);
|
|
155
|
+
this.rowElements.push(rowEl);
|
|
156
|
+
}
|
|
157
|
+
// Update aria attributes
|
|
158
|
+
for (let r = 0; r < rows; r++) {
|
|
159
|
+
this.rowElements[r].setAttribute("aria-posinset", String(r + 1));
|
|
160
|
+
this.rowElements[r].setAttribute("aria-setsize", String(rows));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
dispose() {
|
|
164
|
+
if (this.disposed)
|
|
165
|
+
return;
|
|
166
|
+
this.disposed = true;
|
|
167
|
+
if (this.throttleTimer !== null) {
|
|
168
|
+
clearTimeout(this.throttleTimer);
|
|
169
|
+
this.throttleTimer = null;
|
|
170
|
+
}
|
|
171
|
+
if (this.treeContainer.parentElement) {
|
|
172
|
+
this.treeContainer.parentElement.removeChild(this.treeContainer);
|
|
173
|
+
}
|
|
174
|
+
if (this.liveRegion.parentElement) {
|
|
175
|
+
this.liveRegion.parentElement.removeChild(this.liveRegion);
|
|
176
|
+
}
|
|
177
|
+
this.rowElements = [];
|
|
178
|
+
}
|
|
179
|
+
// -----------------------------------------------------------------------
|
|
180
|
+
// Internal
|
|
181
|
+
// -----------------------------------------------------------------------
|
|
182
|
+
performUpdate() {
|
|
183
|
+
const grid = this.grid;
|
|
184
|
+
const rows = Math.min(this.rows, this.rowElements.length);
|
|
185
|
+
for (let r = 0; r < rows; r++) {
|
|
186
|
+
if (!grid.isDirty(r))
|
|
187
|
+
continue;
|
|
188
|
+
const text = extractRowText(grid, r);
|
|
189
|
+
const el = this.rowElements[r];
|
|
190
|
+
if (el.textContent !== text) {
|
|
191
|
+
el.textContent = text;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=accessibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../src/accessibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,GAAW;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACvC,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,MAAM,OAAO,oBAAoB;IACvB,UAAU,CAAc;IACxB,aAAa,CAAc;IAC3B,WAAW,CAAgB;IAC3B,IAAI,CAAW;IACf,IAAI,CAAS;IACb,IAAI,CAAS;IACb,SAAS,CAAc;IACvB,QAAQ,GAAG,KAAK,CAAC;IAEzB,iDAAiD;IACzC,MAAM,CAAU,WAAW,GAAG,GAAG,CAAC;IAElC,aAAa,GAAyC,IAAI,CAAC;IAC3D,eAAe,GAAG,KAAK,CAAC;IAEhC,YAAY,SAAsB,EAAE,IAAc,EAAE,IAAY,EAAE,IAAY;QAC5E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,sDAAsD;QACtD,uEAAuE;QACvE,sDAAsD;QACtD,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QACjE,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;YACtC,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,GAAG;YACT,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,GAAG;YACZ,aAAa,EAAE,MAAM;YACrB,kEAAkE;YAClE,sDAAsD;YACtD,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QAEH,6BAA6B;QAC7B,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC5C,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAClC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnD,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE1C,kEAAkE;QAClE,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE;YACnC,QAAQ,EAAE,UAAU;YACpB,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,GAAG;YACT,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,GAAG;YACZ,aAAa,EAAE,MAAM;YACrB,IAAI,EAAE,eAAe;YACrB,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,QAAQ;SACrB,CAAC,CAAC;QACH,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAE1B,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAChC,wEAAwE;YACxE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;QAErB,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;YAC1B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;gBAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,CAAC;QACH,CAAC,EAAE,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,IAAY,EAAE,WAAmC,QAAQ;QAChE,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAE1B,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAEpD,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAElC,iDAAiD;QACjD,OAAO,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YACzC,IAAI,KAAK;gBAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAc,EAAE,IAAY,EAAE,IAAY;QAChD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,4CAA4C;QAC5C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;YACtC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;YAClC,IAAI,EAAE;gBAAE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC5C,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAClC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QAED,yBAAyB;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACjE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAChC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;YACrC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;YAClC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,0EAA0E;IAC1E,WAAW;IACX,0EAA0E;IAElE,aAAa;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAAE,SAAS;YAC/B,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YACrC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,EAAE,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;gBAC5B,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addon.d.ts","sourceRoot":"","sources":["../src/addon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
package/dist/addon.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addon.js","sourceRoot":"","sources":["../src/addon.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.d.ts","sourceRoot":"","sources":["../../src/addons/fit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;GAEG;AACH,qBAAa,QAAS,YAAW,cAAc;IAC7C,OAAO,CAAC,QAAQ,CAA4B;IAE5C,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAIrC,OAAO,IAAI,IAAI;IAIf;;;OAGG;IACH,iBAAiB,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAY1D;;OAEG;IACH,GAAG,IAAI,IAAI;CAQZ"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { calculateFit } from "../fit.js";
|
|
2
|
+
/**
|
|
3
|
+
* Addon that fits the terminal to its container element.
|
|
4
|
+
*/
|
|
5
|
+
export class FitAddon {
|
|
6
|
+
terminal = null;
|
|
7
|
+
activate(terminal) {
|
|
8
|
+
this.terminal = terminal;
|
|
9
|
+
}
|
|
10
|
+
dispose() {
|
|
11
|
+
this.terminal = null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Calculate the dimensions that would fit the terminal's container.
|
|
15
|
+
* Returns null if the terminal is not attached or dimensions can't be calculated.
|
|
16
|
+
*/
|
|
17
|
+
proposeDimensions() {
|
|
18
|
+
if (!this.terminal)
|
|
19
|
+
return null;
|
|
20
|
+
const container = this.terminal.element;
|
|
21
|
+
if (!container)
|
|
22
|
+
return null;
|
|
23
|
+
const { width, height } = this.terminal.getCellSize();
|
|
24
|
+
if (width <= 0 || height <= 0)
|
|
25
|
+
return null;
|
|
26
|
+
return calculateFit(container, width, height);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fit the terminal to its container by resizing.
|
|
30
|
+
*/
|
|
31
|
+
fit() {
|
|
32
|
+
const dims = this.proposeDimensions();
|
|
33
|
+
if (!dims || !this.terminal)
|
|
34
|
+
return;
|
|
35
|
+
if (dims.cols !== this.terminal.cols || dims.rows !== this.terminal.rows) {
|
|
36
|
+
this.terminal.resize(dims.cols, dims.rows);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=fit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.js","sourceRoot":"","sources":["../../src/addons/fit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC;;GAEG;AACH,MAAM,OAAO,QAAQ;IACX,QAAQ,GAAuB,IAAI,CAAC;IAE5C,QAAQ,CAAC,QAAqB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,iBAAiB;QACf,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAE5B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACtD,IAAI,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,OAAO,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,GAAG;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEpC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACzE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { CellGrid } from "@next_term/core";
|
|
2
|
+
import type { ITerminalAddon } from "../addon.js";
|
|
3
|
+
import type { WebTerminal } from "../web-terminal.js";
|
|
4
|
+
export interface SearchMatch {
|
|
5
|
+
row: number;
|
|
6
|
+
startCol: number;
|
|
7
|
+
endCol: number;
|
|
8
|
+
}
|
|
9
|
+
export interface SearchOptions {
|
|
10
|
+
caseSensitive?: boolean;
|
|
11
|
+
wholeWord?: boolean;
|
|
12
|
+
regex?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extract the text content of a single row from a CellGrid.
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractRowText(grid: CellGrid, row: number): string;
|
|
18
|
+
/**
|
|
19
|
+
* Find all matches of a query in a grid.
|
|
20
|
+
*/
|
|
21
|
+
export declare function findAllMatches(grid: CellGrid, query: string, options?: SearchOptions): SearchMatch[];
|
|
22
|
+
export declare class SearchAddon implements ITerminalAddon {
|
|
23
|
+
private terminal;
|
|
24
|
+
private matches;
|
|
25
|
+
private currentMatchIndex;
|
|
26
|
+
private lastQuery;
|
|
27
|
+
private lastOptions;
|
|
28
|
+
activate(terminal: WebTerminal): void;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Search forward for the next match of the given query.
|
|
32
|
+
* Returns the match or null if none found.
|
|
33
|
+
*/
|
|
34
|
+
findNext(query: string, options?: SearchOptions): SearchMatch | null;
|
|
35
|
+
/**
|
|
36
|
+
* Search backward for the previous match of the given query.
|
|
37
|
+
* Returns the match or null if none found.
|
|
38
|
+
*/
|
|
39
|
+
findPrevious(query: string, options?: SearchOptions): SearchMatch | null;
|
|
40
|
+
/**
|
|
41
|
+
* Clear all search state and highlights.
|
|
42
|
+
*/
|
|
43
|
+
clearSearch(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get all current matches.
|
|
46
|
+
*/
|
|
47
|
+
getMatches(): SearchMatch[];
|
|
48
|
+
/**
|
|
49
|
+
* Get the current highlighted match.
|
|
50
|
+
*/
|
|
51
|
+
getCurrentMatch(): SearchMatch | null;
|
|
52
|
+
private performSearch;
|
|
53
|
+
private updateHighlights;
|
|
54
|
+
private optionsEqual;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/addons/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAMD;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,aAAa,GACtB,WAAW,EAAE,CAoDf;AAMD,qBAAa,WAAY,YAAW,cAAc;IAChD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,iBAAiB,CAAM;IAC/B,OAAO,CAAC,SAAS,CAAM;IACvB,OAAO,CAAC,WAAW,CAAqB;IAExC,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAIrC,OAAO,IAAI,IAAI;IAKf;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,IAAI;IAepE;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,IAAI;IAgBxE;;OAEG;IACH,WAAW,IAAI,IAAI;IAUnB;;OAEG;IACH,UAAU,IAAI,WAAW,EAAE;IAI3B;;OAEG;IACH,eAAe,IAAI,WAAW,GAAG,IAAI;IAWrC,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,YAAY;CASrB"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Helpers
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
/**
|
|
5
|
+
* Extract the text content of a single row from a CellGrid.
|
|
6
|
+
*/
|
|
7
|
+
export function extractRowText(grid, row) {
|
|
8
|
+
let line = "";
|
|
9
|
+
for (let col = 0; col < grid.cols; col++) {
|
|
10
|
+
const cp = grid.getCodepoint(row, col);
|
|
11
|
+
line += cp > 0x20 ? String.fromCodePoint(cp) : " ";
|
|
12
|
+
}
|
|
13
|
+
return line;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Find all matches of a query in a grid.
|
|
17
|
+
*/
|
|
18
|
+
export function findAllMatches(grid, query, options) {
|
|
19
|
+
if (!query)
|
|
20
|
+
return [];
|
|
21
|
+
const caseSensitive = options?.caseSensitive ?? false;
|
|
22
|
+
const wholeWord = options?.wholeWord ?? false;
|
|
23
|
+
const useRegex = options?.regex ?? false;
|
|
24
|
+
let regex;
|
|
25
|
+
try {
|
|
26
|
+
let pattern;
|
|
27
|
+
if (useRegex) {
|
|
28
|
+
pattern = query;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Escape special regex characters for literal search
|
|
32
|
+
pattern = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
33
|
+
}
|
|
34
|
+
if (wholeWord) {
|
|
35
|
+
pattern = `\\b${pattern}\\b`;
|
|
36
|
+
}
|
|
37
|
+
const flags = caseSensitive ? "g" : "gi";
|
|
38
|
+
regex = new RegExp(pattern, flags);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Invalid regex — return no matches
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const matches = [];
|
|
45
|
+
for (let row = 0; row < grid.rows; row++) {
|
|
46
|
+
const text = extractRowText(grid, row);
|
|
47
|
+
let m;
|
|
48
|
+
// Reset lastIndex for each row
|
|
49
|
+
regex.lastIndex = 0;
|
|
50
|
+
while (true) {
|
|
51
|
+
m = regex.exec(text);
|
|
52
|
+
if (m === null)
|
|
53
|
+
break;
|
|
54
|
+
matches.push({
|
|
55
|
+
row,
|
|
56
|
+
startCol: m.index,
|
|
57
|
+
endCol: m.index + m[0].length - 1,
|
|
58
|
+
});
|
|
59
|
+
// Prevent infinite loops on zero-length matches
|
|
60
|
+
if (m[0].length === 0) {
|
|
61
|
+
regex.lastIndex++;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return matches;
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// SearchAddon
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
export class SearchAddon {
|
|
71
|
+
terminal = null;
|
|
72
|
+
matches = [];
|
|
73
|
+
currentMatchIndex = -1;
|
|
74
|
+
lastQuery = "";
|
|
75
|
+
lastOptions = {};
|
|
76
|
+
activate(terminal) {
|
|
77
|
+
this.terminal = terminal;
|
|
78
|
+
}
|
|
79
|
+
dispose() {
|
|
80
|
+
this.clearSearch();
|
|
81
|
+
this.terminal = null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Search forward for the next match of the given query.
|
|
85
|
+
* Returns the match or null if none found.
|
|
86
|
+
*/
|
|
87
|
+
findNext(query, options) {
|
|
88
|
+
if (!this.terminal)
|
|
89
|
+
return null;
|
|
90
|
+
// Re-run search if query or options changed
|
|
91
|
+
if (query !== this.lastQuery || !this.optionsEqual(options)) {
|
|
92
|
+
this.performSearch(query, options);
|
|
93
|
+
}
|
|
94
|
+
if (this.matches.length === 0)
|
|
95
|
+
return null;
|
|
96
|
+
this.currentMatchIndex = (this.currentMatchIndex + 1) % this.matches.length;
|
|
97
|
+
this.updateHighlights();
|
|
98
|
+
return this.matches[this.currentMatchIndex];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Search backward for the previous match of the given query.
|
|
102
|
+
* Returns the match or null if none found.
|
|
103
|
+
*/
|
|
104
|
+
findPrevious(query, options) {
|
|
105
|
+
if (!this.terminal)
|
|
106
|
+
return null;
|
|
107
|
+
// Re-run search if query or options changed
|
|
108
|
+
if (query !== this.lastQuery || !this.optionsEqual(options)) {
|
|
109
|
+
this.performSearch(query, options);
|
|
110
|
+
}
|
|
111
|
+
if (this.matches.length === 0)
|
|
112
|
+
return null;
|
|
113
|
+
this.currentMatchIndex =
|
|
114
|
+
this.currentMatchIndex <= 0 ? this.matches.length - 1 : this.currentMatchIndex - 1;
|
|
115
|
+
this.updateHighlights();
|
|
116
|
+
return this.matches[this.currentMatchIndex];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Clear all search state and highlights.
|
|
120
|
+
*/
|
|
121
|
+
clearSearch() {
|
|
122
|
+
this.matches = [];
|
|
123
|
+
this.currentMatchIndex = -1;
|
|
124
|
+
this.lastQuery = "";
|
|
125
|
+
this.lastOptions = {};
|
|
126
|
+
if (this.terminal) {
|
|
127
|
+
this.terminal.setHighlights([]);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get all current matches.
|
|
132
|
+
*/
|
|
133
|
+
getMatches() {
|
|
134
|
+
return this.matches;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get the current highlighted match.
|
|
138
|
+
*/
|
|
139
|
+
getCurrentMatch() {
|
|
140
|
+
if (this.currentMatchIndex < 0 || this.currentMatchIndex >= this.matches.length) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
return this.matches[this.currentMatchIndex];
|
|
144
|
+
}
|
|
145
|
+
// -----------------------------------------------------------------------
|
|
146
|
+
// Internal
|
|
147
|
+
// -----------------------------------------------------------------------
|
|
148
|
+
performSearch(query, options) {
|
|
149
|
+
this.lastQuery = query;
|
|
150
|
+
this.lastOptions = options ? { ...options } : {};
|
|
151
|
+
this.currentMatchIndex = -1;
|
|
152
|
+
if (!this.terminal) {
|
|
153
|
+
this.matches = [];
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const grid = this.terminal.activeGrid;
|
|
157
|
+
this.matches = findAllMatches(grid, query, options);
|
|
158
|
+
}
|
|
159
|
+
updateHighlights() {
|
|
160
|
+
if (!this.terminal)
|
|
161
|
+
return;
|
|
162
|
+
const highlights = this.matches.map((m, i) => ({
|
|
163
|
+
row: m.row,
|
|
164
|
+
startCol: m.startCol,
|
|
165
|
+
endCol: m.endCol,
|
|
166
|
+
isCurrent: i === this.currentMatchIndex,
|
|
167
|
+
}));
|
|
168
|
+
this.terminal.setHighlights(highlights);
|
|
169
|
+
}
|
|
170
|
+
optionsEqual(options) {
|
|
171
|
+
const a = this.lastOptions;
|
|
172
|
+
const b = options ?? {};
|
|
173
|
+
return ((a.caseSensitive ?? false) === (b.caseSensitive ?? false) &&
|
|
174
|
+
(a.wholeWord ?? false) === (b.wholeWord ?? false) &&
|
|
175
|
+
(a.regex ?? false) === (b.regex ?? false));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/addons/search.ts"],"names":[],"mappings":"AAoBA,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc,EAAE,GAAW;IACxD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACvC,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAc,EACd,KAAa,EACb,OAAuB;IAEvB,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,MAAM,aAAa,GAAG,OAAO,EAAE,aAAa,IAAI,KAAK,CAAC;IACtD,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC;IAC9C,MAAM,QAAQ,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;IAEzC,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,OAAe,CAAC;QACpB,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,qDAAqD;YACrD,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,GAAG,MAAM,OAAO,KAAK,CAAC;QAC/B,CAAC;QAED,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,oCAAoC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACvC,IAAI,CAAyB,CAAC;QAE9B,+BAA+B;QAC/B,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;QACpB,OAAO,IAAI,EAAE,CAAC;YACZ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,IAAI,CAAC,KAAK,IAAI;gBAAE,MAAM;YACtB,OAAO,CAAC,IAAI,CAAC;gBACX,GAAG;gBACH,QAAQ,EAAE,CAAC,CAAC,KAAK;gBACjB,MAAM,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;aAClC,CAAC,CAAC;YACH,gDAAgD;YAChD,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,OAAO,WAAW;IACd,QAAQ,GAAuB,IAAI,CAAC;IACpC,OAAO,GAAkB,EAAE,CAAC;IAC5B,iBAAiB,GAAG,CAAC,CAAC,CAAC;IACvB,SAAS,GAAG,EAAE,CAAC;IACf,WAAW,GAAkB,EAAE,CAAC;IAExC,QAAQ,CAAC,QAAqB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO;QACL,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAa,EAAE,OAAuB;QAC7C,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEhC,4CAA4C;QAC5C,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,CAAC,iBAAiB,GAAG,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5E,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,KAAa,EAAE,OAAuB;QACjD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEhC,4CAA4C;QAC5C,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE3C,IAAI,CAAC,iBAAiB;YACpB,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QACrF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;QACpB,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,eAAe;QACb,IAAI,IAAI,CAAC,iBAAiB,GAAG,CAAC,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAChF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC9C,CAAC;IAED,0EAA0E;IAC1E,WAAW;IACX,0EAA0E;IAElE,aAAa,CAAC,KAAa,EAAE,OAAuB;QAC1D,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC;QAE5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAEO,gBAAgB;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAE3B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7C,GAAG,EAAE,CAAC,CAAC,GAAG;YACV,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,SAAS,EAAE,CAAC,KAAK,IAAI,CAAC,iBAAiB;SACxC,CAAC,CAAC,CAAC;QAEJ,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAEO,YAAY,CAAC,OAAuB;QAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;QAC3B,MAAM,CAAC,GAAG,OAAO,IAAI,EAAE,CAAC;QACxB,OAAO,CACL,CAAC,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC;YACzD,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC;YACjD,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,CAC1C,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CellGrid } from "@next_term/core";
|
|
2
|
+
import type { ITerminalAddon } from "../addon.js";
|
|
3
|
+
import type { WebTerminal } from "../web-terminal.js";
|
|
4
|
+
export interface LinkMatch {
|
|
5
|
+
row: number;
|
|
6
|
+
startCol: number;
|
|
7
|
+
endCol: number;
|
|
8
|
+
url: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Find all URLs in the visible rows of a grid.
|
|
12
|
+
*/
|
|
13
|
+
export declare function findLinks(grid: CellGrid): LinkMatch[];
|
|
14
|
+
export declare class WebLinksAddon implements ITerminalAddon {
|
|
15
|
+
private terminal;
|
|
16
|
+
private handler;
|
|
17
|
+
private links;
|
|
18
|
+
private currentHoverLink;
|
|
19
|
+
private mouseMoveHandler;
|
|
20
|
+
private clickHandler;
|
|
21
|
+
constructor(handler?: (url: string) => void);
|
|
22
|
+
activate(terminal: WebTerminal): void;
|
|
23
|
+
dispose(): void;
|
|
24
|
+
private refreshLinks;
|
|
25
|
+
private getCellPosition;
|
|
26
|
+
private findLinkAt;
|
|
27
|
+
private onMouseMove;
|
|
28
|
+
private onClick;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=web-links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-links.d.ts","sourceRoot":"","sources":["../../src/addons/web-links.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAwBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,CA4BrD;AAMD,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,gBAAgB,CAA0B;IAElD,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,YAAY,CAA0C;gBAElD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;IAW3C,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAcrC,OAAO,IAAI,IAAI;IAyBf,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,eAAe;IAmBvB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,WAAW;IAsBnB,OAAO,CAAC,OAAO;CAchB"}
|