@cplieger/web-terminal-ui 8.3.0 → 8.3.2

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.
@@ -220,7 +220,8 @@ export interface PaneKernel extends PaneHandle {
220
220
  * gets when the closing transition ends. */
221
221
  setHidden(value: boolean): void;
222
222
  /** The shell is about to slide this pane's box: nothing it measures from now
223
- * until its viewport settles is final, and the settle sends the size. */
223
+ * until its viewport settles is final, and the settle sends the size. Live
224
+ * panes only: a failed pane is torn down before the split next opens. */
224
225
  holdGeometry(): void;
225
226
  /** Whether this pane's input is a stop in the document's Tab order. On while
226
227
  * the split is open and the pane shows a tab, so Tab runs left input, divider,
@@ -437,15 +438,10 @@ function buildPaneInto(
437
438
  let hidden = false;
438
439
  let rootReleased = false;
439
440
 
440
- let ready = false;
441
441
  let firstFrameRendered = false;
442
442
  let fontsLoaded = false;
443
443
  let wsOpen = false;
444
444
  function markReady(): void {
445
- if (ready) {
446
- return;
447
- }
448
- ready = true;
449
445
  connState.setLoaded();
450
446
  services.loading.firstFrame();
451
447
  }
@@ -981,7 +977,7 @@ function buildPaneInto(
981
977
  }
982
978
  // Nobody owns the keyboard: focus in a shadow root, a dialog or an ARIA
983
979
  // widget all report non-body and all bail.
984
- if (doc.activeElement !== null && doc.activeElement !== doc.body) {
980
+ if (doc.activeElement !== doc.body) {
985
981
  return;
986
982
  }
987
983
  if (composition.isComposing()) {
@@ -1514,9 +1510,7 @@ function buildPaneInto(
1514
1510
  hidden = value;
1515
1511
  },
1516
1512
  holdGeometry() {
1517
- if (!destroyed) {
1518
- viewport.beginTransition();
1519
- }
1513
+ viewport.beginTransition();
1520
1514
  },
1521
1515
  setTabStop(value) {
1522
1516
  input.tabIndex = value ? 0 : -1;
@@ -214,7 +214,6 @@ export function localScrollbackStorage(
214
214
  function sweep(): void {
215
215
  const now = Date.now();
216
216
  const live: { key: string; savedAt: number; chars: number }[] = [];
217
- let total = 0;
218
217
  for (const entry of ownEntries()) {
219
218
  // An unreadable timestamp is treated as expired: the kernel would refuse
220
219
  // the entry anyway, so keeping it only consumes quota.
@@ -223,10 +222,6 @@ export function localScrollbackStorage(
223
222
  continue;
224
223
  }
225
224
  live.push({ key: entry.key, savedAt: entry.savedAt, chars: entry.chars });
226
- total += entry.chars;
227
- }
228
- if (total <= maxBytes) {
229
- return;
230
225
  }
231
226
  // Newest first, then keep entries while they fit and drop the rest: an entry
232
227
  // the user last saw a minute ago is worth more than one from this morning.
@@ -12,9 +12,6 @@ export function selectionTextWithin(container: Element): string {
12
12
  return "";
13
13
  }
14
14
  const text = sel.toString();
15
- if (text.length === 0) {
16
- return "";
17
- }
18
15
  for (let i = 0; i < sel.rangeCount; i++) {
19
16
  const range = sel.getRangeAt(i);
20
17
  if (!container.contains(range.startContainer) || !container.contains(range.endContainer)) {
@@ -549,9 +549,6 @@ function createShellInto(
549
549
  applyRatioVar();
550
550
  }
551
551
  function fireSplitChange(): void {
552
- if (changeListeners.size === 0) {
553
- return;
554
- }
555
552
  const state = splitState();
556
553
  for (const cb of [...changeListeners]) {
557
554
  cb(state);
@@ -608,9 +605,6 @@ function createShellInto(
608
605
  // may rest on the empty pane the replacement is headed for, so the handle faces
609
606
  // where the new tab will land.
610
607
  function select(side: PaneSide): boolean {
611
- if (!isPaneSide(side)) {
612
- return false;
613
- }
614
608
  const state = paneAt(side)?.state();
615
609
  if (state !== "shown" && !(state === "empty" && !anyShown())) {
616
610
  return false;
@@ -1064,7 +1058,7 @@ function createShellInto(
1064
1058
  return;
1065
1059
  }
1066
1060
  for (const feature of features) {
1067
- if (destroyed || kernel.isDestroyed()) {
1061
+ if (kernel.isDestroyed()) {
1068
1062
  return;
1069
1063
  }
1070
1064
  const outcome = await kernel.setupFeature(feature);
@@ -1072,9 +1066,6 @@ function createShellInto(
1072
1066
  failPane(slot, { phase: "feature-setup", feature: outcome.feature, cause: outcome.cause });
1073
1067
  return;
1074
1068
  }
1075
- if (outcome.status === "aborted") {
1076
- return;
1077
- }
1078
1069
  }
1079
1070
  }
1080
1071
  function buildSecondary(slot: Slot): void {
@@ -1231,7 +1222,7 @@ function createShellInto(
1231
1222
  return true;
1232
1223
  }
1233
1224
  function closeSide(side: PaneSide): boolean {
1234
- if (!isPaneSide(side) || !splitOpen || destroyed) {
1225
+ if (!splitOpen || destroyed) {
1235
1226
  return false;
1236
1227
  }
1237
1228
  const squeezed = slotAt(side);
@@ -1266,9 +1257,6 @@ function createShellInto(
1266
1257
  );
1267
1258
  }
1268
1259
  function onShellResize(): void {
1269
- if (destroyed) {
1270
- return;
1271
- }
1272
1260
  paintShellNarrow();
1273
1261
  for (const p of builtPanes()) {
1274
1262
  p.updateNarrow();
@@ -1427,9 +1415,6 @@ function createShellInto(
1427
1415
 
1428
1416
  let rootReleased = false;
1429
1417
  function cleanupRuntime(): void {
1430
- if (destroyed) {
1431
- return;
1432
- }
1433
1418
  destroyed = true;
1434
1419
  // The tracked stores are about to become unreachable, and the connections
1435
1420
  // whose epochs the save is filed under go with the drain.
@@ -1441,7 +1426,6 @@ function createShellInto(
1441
1426
  if (destroyed) {
1442
1427
  return;
1443
1428
  }
1444
- primaryKernel.markFailed();
1445
1429
  cleanupRuntime();
1446
1430
  dismissLoadingOverlay();
1447
1431
  let handled = false;
@@ -1517,21 +1501,12 @@ function createShellInto(
1517
1501
  selectedPane().focus();
1518
1502
  },
1519
1503
  send(bytes) {
1520
- if (destroyed) {
1521
- return;
1522
- }
1523
1504
  selectedPane().send(bytes);
1524
1505
  },
1525
1506
  reset() {
1526
- if (destroyed) {
1527
- return;
1528
- }
1529
1507
  selectedPane().reset();
1530
1508
  },
1531
1509
  reattach() {
1532
- if (destroyed) {
1533
- return;
1534
- }
1535
1510
  selectedPane().reattach();
1536
1511
  },
1537
1512
  destroy() {
@@ -237,9 +237,6 @@ export function createSplitHandle(shell: SplitHandleShell): SplitHandle {
237
237
  return;
238
238
  }
239
239
  const state = split.state();
240
- if (!state.open || state.collapsed) {
241
- return;
242
- }
243
240
  ev.preventDefault();
244
241
  const span = root.clientWidth - SPLIT_GUTTER_PX;
245
242
  const { min, max } = bounds();
package/src/predict.ts CHANGED
@@ -31,7 +31,6 @@ export function createPredictor(): Predictor {
31
31
  let predCol = 0;
32
32
  let predActive = false;
33
33
  let predPendingWrap = false;
34
- let predFrozen = false;
35
34
  let cols = 80;
36
35
  let rows = 30;
37
36
  let onChange: (() => void) | null = null;
@@ -40,8 +39,6 @@ export function createPredictor(): Predictor {
40
39
  predRow = 0;
41
40
  predCol = 0;
42
41
  predActive = false;
43
- predPendingWrap = false;
44
- predFrozen = false;
45
42
  onChange?.();
46
43
  }
47
44
 
@@ -73,23 +70,17 @@ export function createPredictor(): Predictor {
73
70
  predRow = serverRow;
74
71
  predCol = serverCol;
75
72
  predPendingWrap = false;
76
- predFrozen = cursorHidden ?? false;
77
- predActive = !predFrozen;
73
+ predActive = !(cursorHidden ?? false);
78
74
  onChange?.();
79
75
  },
80
76
  applyInput(bytes) {
81
- if (!predActive || predFrozen) {
77
+ if (!predActive) {
82
78
  return;
83
79
  }
84
80
  let i = 0;
85
81
  while (i < bytes.length) {
86
82
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- index checked by loop condition
87
83
  const b = bytes[i]!;
88
- if (b === 0x1b) {
89
- predActive = false;
90
- onChange?.();
91
- return;
92
- }
93
84
  if (b === 0x08 || b === 0x7f) {
94
85
  predPendingWrap = false;
95
86
  if (predCol > 0) {
package/src/viewport.ts CHANGED
@@ -9,7 +9,15 @@ import { windowOf } from "./kernel/realm.js";
9
9
 
10
10
  // Long enough to bridge the iOS keyboard slide (~250ms) with margin for fonts
11
11
  // and reflow.
12
- const SETTLE_MS = 350;
12
+ let SETTLE_MS = 350;
13
+
14
+ /** @internal Test seam: arm every settle started from now on at `ms`; returns the
15
+ * previous value so the caller can restore it. */
16
+ export function setSettleMs(ms: number): number {
17
+ const previous = SETTLE_MS;
18
+ SETTLE_MS = ms;
19
+ return previous;
20
+ }
13
21
 
14
22
  /** The visual viewport against the layout viewport, in whole CSS px. */
15
23
  interface KeyboardGeometry {