@vizejs/fresco 0.716.0 → 0.718.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-OEhyYUxd.d.mts → accessibility-DwzT925M.d.mts} +46 -5
- package/dist/accessibility-DwzT925M.d.mts.map +1 -0
- package/dist/{app-CIX6NAW-.mjs → app-C_wFlWSV.mjs} +443 -123
- package/dist/app-C_wFlWSV.mjs.map +1 -0
- package/dist/app-_QmZ-PoH.d.mts +270 -0
- package/dist/app-_QmZ-PoH.d.mts.map +1 -0
- package/dist/ascii-font/index.d.mts +60 -0
- package/dist/ascii-font/index.d.mts.map +1 -0
- package/dist/ascii-font/index.mjs +68 -0
- package/dist/ascii-font/index.mjs.map +1 -0
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.mjs +2 -2
- package/dist/components-DzkL-yHj.mjs +6165 -0
- package/dist/components-DzkL-yHj.mjs.map +1 -0
- package/dist/composables/index.d.mts +3 -3
- package/dist/composables/index.mjs +4 -4
- package/dist/{composables-DbJGVNSG.mjs → composables-BJeirPSH.mjs} +116 -55
- package/dist/composables-BJeirPSH.mjs.map +1 -0
- package/dist/{index-CWRginDz.d.mts → index-B3zQ6E-5.d.mts} +1099 -337
- package/dist/index-B3zQ6E-5.d.mts.map +1 -0
- package/dist/{index-Dikou9bu.d.mts → index-Ddp2Txtm.d.mts} +52 -4
- package/dist/index-Ddp2Txtm.d.mts.map +1 -0
- package/dist/index.d.mts +98 -7
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +262 -5
- package/dist/index.mjs.map +1 -1
- package/dist/{protocol-D8xt3DG7.d.mts → protocol-DavoeNLn.d.mts} +14 -4
- package/dist/{protocol-D8xt3DG7.d.mts.map → protocol-DavoeNLn.d.mts.map} +1 -1
- package/dist/qr-code/index.d.mts +101 -0
- package/dist/qr-code/index.d.mts.map +1 -0
- package/dist/qr-code/index.mjs +88 -0
- package/dist/qr-code/index.mjs.map +1 -0
- package/dist/testing/index.d.mts +3 -3
- package/dist/testing/index.mjs +1 -1
- package/dist/{useApp-CVB2jNCO.d.mts → useApp-vIRJ5Th3.d.mts} +34 -8
- package/dist/useApp-vIRJ5Th3.d.mts.map +1 -0
- package/dist/{useVirtualViewport-pPZWmwUC.mjs → useBoxMetrics-lF5Myjc7.mjs} +66 -6
- package/dist/useBoxMetrics-lF5Myjc7.mjs.map +1 -0
- package/package.json +14 -6
- package/dist/accessibility-OEhyYUxd.d.mts.map +0 -1
- package/dist/app-CIX6NAW-.mjs.map +0 -1
- package/dist/app-CKsTWQuP.d.mts +0 -154
- package/dist/app-CKsTWQuP.d.mts.map +0 -1
- package/dist/components-D9SeB0Be.mjs +0 -3331
- package/dist/components-D9SeB0Be.mjs.map +0 -1
- package/dist/composables-DbJGVNSG.mjs.map +0 -1
- package/dist/index-CWRginDz.d.mts.map +0 -1
- package/dist/index-Dikou9bu.d.mts.map +0 -1
- package/dist/useApp-CVB2jNCO.d.mts.map +0 -1
- package/dist/useVirtualViewport-pPZWmwUC.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { format } from "node:util";
|
|
2
|
-
import { computed, createRenderer, defineComponent, h, inject, isRef, onUnmounted, ref, shallowRef, watch } from "vue";
|
|
2
|
+
import { computed, createRenderer, defineComponent, h, inject, isRef, nextTick, onUnmounted, provide, ref, shallowRef, watch } from "vue";
|
|
3
3
|
//#region src/renderPayload.ts
|
|
4
4
|
const displays = ["flex", "none"];
|
|
5
5
|
const positions = [
|
|
@@ -89,6 +89,11 @@ function numberValue(value) {
|
|
|
89
89
|
function booleanValue(value) {
|
|
90
90
|
return typeof value === "boolean" ? value : void 0;
|
|
91
91
|
}
|
|
92
|
+
function stringLines(value) {
|
|
93
|
+
if (!Array.isArray(value)) return void 0;
|
|
94
|
+
const lines = value.filter((line) => typeof line === "string");
|
|
95
|
+
return lines.length > 0 ? lines : void 0;
|
|
96
|
+
}
|
|
92
97
|
function enabledValue(value) {
|
|
93
98
|
return value === true ? true : void 0;
|
|
94
99
|
}
|
|
@@ -199,6 +204,15 @@ function frescoNodeToRenderNode(node) {
|
|
|
199
204
|
}
|
|
200
205
|
return renderNode;
|
|
201
206
|
}
|
|
207
|
+
if (node.type === "raw") {
|
|
208
|
+
const renderNode = {
|
|
209
|
+
...common,
|
|
210
|
+
nodeType: "raw"
|
|
211
|
+
};
|
|
212
|
+
const lines = stringLines(node.props.lines);
|
|
213
|
+
if (lines) renderNode.lines = lines;
|
|
214
|
+
return renderNode;
|
|
215
|
+
}
|
|
202
216
|
const renderNode = {
|
|
203
217
|
...common,
|
|
204
218
|
nodeType: "input"
|
|
@@ -207,12 +221,16 @@ function frescoNodeToRenderNode(node) {
|
|
|
207
221
|
const placeholder = stringValue$1(node.props.placeholder);
|
|
208
222
|
const focused = booleanValue(firstValue(node.props, "focused", "focus"));
|
|
209
223
|
const cursor = numberValue(node.props.cursor);
|
|
224
|
+
const selectionStart = numberValue(firstValue(node.props, "selectionStart", "selection_start"));
|
|
225
|
+
const selectionEnd = numberValue(firstValue(node.props, "selectionEnd", "selection_end"));
|
|
210
226
|
const mask = booleanValue(node.props.mask);
|
|
211
227
|
const maskChar = stringValue$1(firstValue(node.props, "maskChar", "mask_char", "mask-char"));
|
|
212
228
|
if (value !== void 0) renderNode.value = value;
|
|
213
229
|
if (placeholder !== void 0) renderNode.placeholder = placeholder;
|
|
214
230
|
if (focused !== void 0) renderNode.focused = focused;
|
|
215
231
|
if (cursor !== void 0) renderNode.cursor = cursor;
|
|
232
|
+
if (selectionStart !== void 0) renderNode.selectionStart = selectionStart;
|
|
233
|
+
if (selectionEnd !== void 0) renderNode.selectionEnd = selectionEnd;
|
|
216
234
|
if (mask !== void 0) renderNode.mask = mask;
|
|
217
235
|
if (maskChar !== void 0) renderNode.maskChar = maskChar;
|
|
218
236
|
return renderNode;
|
|
@@ -371,6 +389,7 @@ function useApp() {
|
|
|
371
389
|
* useFocus - Focus management composable
|
|
372
390
|
*/
|
|
373
391
|
const FOCUS_KEY = Symbol("fresco-focus");
|
|
392
|
+
const FOCUS_PARENT_KEY = Symbol("fresco-focus-parent");
|
|
374
393
|
function activeFocusables(focusables) {
|
|
375
394
|
return focusables.filter((focusable) => focusable.isActive);
|
|
376
395
|
}
|
|
@@ -382,38 +401,76 @@ function createFocusManager() {
|
|
|
382
401
|
const activeId = computed(() => focusedId.value ?? void 0);
|
|
383
402
|
const focusables = ref([]);
|
|
384
403
|
const focusableIds = computed(() => activeFocusables(focusables.value).map(({ id }) => id));
|
|
404
|
+
const trapStack = ref([]);
|
|
405
|
+
const activeTrapId = computed(() => trapStack.value.at(-1));
|
|
385
406
|
const isEnabled = ref(true);
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
407
|
+
const findFocusable = (id) => focusables.value.find((focusable) => focusable.id === id);
|
|
408
|
+
const isWithin = (id, rootId) => {
|
|
409
|
+
let currentId = id;
|
|
410
|
+
const visited = /* @__PURE__ */ new Set();
|
|
411
|
+
while (currentId !== null) {
|
|
412
|
+
if (currentId === rootId) return true;
|
|
413
|
+
if (visited.has(currentId)) return false;
|
|
414
|
+
visited.add(currentId);
|
|
415
|
+
currentId = findFocusable(currentId)?.parentId ?? null;
|
|
416
|
+
}
|
|
417
|
+
return false;
|
|
389
418
|
};
|
|
390
|
-
const
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
419
|
+
const allowedByActiveTrap = (id) => {
|
|
420
|
+
const trapId = activeTrapId.value;
|
|
421
|
+
return trapId === void 0 || isWithin(id, trapId);
|
|
422
|
+
};
|
|
423
|
+
const scopedFocusables = () => activeFocusables(focusables.value).filter(({ id }) => allowedByActiveTrap(id));
|
|
424
|
+
const delegatedTarget = (target) => {
|
|
425
|
+
let current = target;
|
|
426
|
+
const visited = /* @__PURE__ */ new Set();
|
|
427
|
+
while (current.delegateFocusTo !== null && !visited.has(current.id)) {
|
|
428
|
+
visited.add(current.id);
|
|
429
|
+
const delegated = findFocusable(current.delegateFocusTo);
|
|
430
|
+
if (!delegated?.isActive || !isWithin(delegated.id, current.id) || !allowedByActiveTrap(delegated.id)) break;
|
|
431
|
+
current = delegated;
|
|
432
|
+
}
|
|
433
|
+
return current;
|
|
395
434
|
};
|
|
396
|
-
const
|
|
397
|
-
const
|
|
435
|
+
const focus = (id) => {
|
|
436
|
+
const target = findFocusable(id);
|
|
437
|
+
if (isEnabled.value && target?.isActive && allowedByActiveTrap(id)) focusedId.value = delegatedTarget(target).id;
|
|
438
|
+
};
|
|
439
|
+
const moveFocus = (offset) => {
|
|
440
|
+
const active = scopedFocusables();
|
|
398
441
|
if (!isEnabled.value || active.length === 0) return;
|
|
399
|
-
const currentIndex =
|
|
400
|
-
|
|
442
|
+
const currentIndex = active.findIndex((focusable) => focusable.id === focusedId.value);
|
|
443
|
+
for (let distance = 1; distance <= active.length; distance += 1) {
|
|
444
|
+
const candidate = active[currentIndex === -1 ? offset === 1 ? distance - 1 : active.length - distance : (currentIndex + offset * distance + active.length * 2) % active.length];
|
|
445
|
+
if (!candidate) continue;
|
|
446
|
+
const resolved = delegatedTarget(candidate);
|
|
447
|
+
if (resolved.id !== focusedId.value || active.length === 1) {
|
|
448
|
+
focusedId.value = resolved.id;
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
401
452
|
};
|
|
453
|
+
const focusNext = () => moveFocus(1);
|
|
454
|
+
const focusPrevious = () => moveFocus(-1);
|
|
402
455
|
const register = (id, options = {}) => {
|
|
403
456
|
const existing = focusables.value.find((focusable) => focusable.id === id);
|
|
404
457
|
if (existing) {
|
|
405
458
|
existing.isActive = options.isActive ?? existing.isActive;
|
|
406
459
|
if ("parentId" in options) existing.parentId = options.parentId ?? null;
|
|
460
|
+
if ("delegateFocusTo" in options) existing.delegateFocusTo = options.delegateFocusTo ?? null;
|
|
407
461
|
} else focusables.value.push({
|
|
408
462
|
id,
|
|
409
463
|
isActive: options.isActive ?? true,
|
|
410
|
-
parentId: options.parentId ?? null
|
|
464
|
+
parentId: options.parentId ?? null,
|
|
465
|
+
delegateFocusTo: options.delegateFocusTo ?? null
|
|
411
466
|
});
|
|
412
467
|
if (options.autoFocus && focusedId.value === null && options.isActive !== false) focus(id);
|
|
413
468
|
};
|
|
414
469
|
const unregister = (id) => {
|
|
415
470
|
const index = focusables.value.findIndex((focusable) => focusable.id === id);
|
|
416
471
|
if (index !== -1) {
|
|
472
|
+
const trapIndex = trapStack.value.indexOf(id);
|
|
473
|
+
if (trapIndex !== -1) trapStack.value.splice(trapIndex);
|
|
417
474
|
focusables.value.splice(index, 1);
|
|
418
475
|
if (focusedId.value === id) focusedId.value = null;
|
|
419
476
|
}
|
|
@@ -422,12 +479,33 @@ function createFocusManager() {
|
|
|
422
479
|
const focusable = focusables.value.find((item) => item.id === id);
|
|
423
480
|
if (!focusable) return;
|
|
424
481
|
focusable.isActive = isActive;
|
|
482
|
+
if (!isActive) {
|
|
483
|
+
const trapIndex = trapStack.value.indexOf(id);
|
|
484
|
+
if (trapIndex !== -1) trapStack.value.splice(trapIndex);
|
|
485
|
+
}
|
|
425
486
|
if (!isActive && focusedId.value === id) focusedId.value = null;
|
|
426
487
|
};
|
|
427
488
|
const setParent = (id, parentId) => {
|
|
428
|
-
const focusable =
|
|
489
|
+
const focusable = findFocusable(id);
|
|
429
490
|
if (!focusable) return;
|
|
430
491
|
focusable.parentId = parentId ?? null;
|
|
492
|
+
if (focusedId.value !== null && !allowedByActiveTrap(focusedId.value)) focusedId.value = null;
|
|
493
|
+
};
|
|
494
|
+
const setDelegate = (id, delegateFocusTo) => {
|
|
495
|
+
const focusable = findFocusable(id);
|
|
496
|
+
if (focusable) focusable.delegateFocusTo = delegateFocusTo ?? null;
|
|
497
|
+
};
|
|
498
|
+
const trapFocus = (id) => {
|
|
499
|
+
if (!findFocusable(id)?.isActive || !allowedByActiveTrap(id)) return;
|
|
500
|
+
if (activeTrapId.value !== id) trapStack.value.push(id);
|
|
501
|
+
if (focusedId.value === null || !isWithin(focusedId.value, id)) focus(id);
|
|
502
|
+
};
|
|
503
|
+
const releaseFocusTrap = (id) => {
|
|
504
|
+
const index = trapStack.value.indexOf(id);
|
|
505
|
+
if (index === -1) return;
|
|
506
|
+
trapStack.value.splice(index);
|
|
507
|
+
const remaining = activeTrapId.value;
|
|
508
|
+
if (remaining !== void 0 && focusedId.value !== null && !isWithin(focusedId.value, remaining)) focus(remaining);
|
|
431
509
|
};
|
|
432
510
|
const hasFocusedDescendant = (id) => {
|
|
433
511
|
let currentId = focusedId.value;
|
|
@@ -436,7 +514,7 @@ function createFocusManager() {
|
|
|
436
514
|
while (true) {
|
|
437
515
|
if (visited.has(currentId)) return false;
|
|
438
516
|
visited.add(currentId);
|
|
439
|
-
const parentId =
|
|
517
|
+
const parentId = findFocusable(currentId)?.parentId ?? null;
|
|
440
518
|
if (parentId === null) return false;
|
|
441
519
|
if (parentId === id) return true;
|
|
442
520
|
currentId = parentId;
|
|
@@ -453,6 +531,7 @@ function createFocusManager() {
|
|
|
453
531
|
focusedId,
|
|
454
532
|
activeId,
|
|
455
533
|
focusableIds,
|
|
534
|
+
activeTrapId,
|
|
456
535
|
isEnabled,
|
|
457
536
|
enableFocus,
|
|
458
537
|
disableFocus,
|
|
@@ -463,23 +542,35 @@ function createFocusManager() {
|
|
|
463
542
|
unregister,
|
|
464
543
|
setActive,
|
|
465
544
|
setParent,
|
|
545
|
+
setDelegate,
|
|
546
|
+
trapFocus,
|
|
547
|
+
releaseFocusTrap,
|
|
466
548
|
hasFocusedDescendant
|
|
467
549
|
};
|
|
468
550
|
}
|
|
551
|
+
/** Make an owning focus target the default parent for nested useFocus calls. */
|
|
552
|
+
function provideFocusScope(parentId) {
|
|
553
|
+
provide(FOCUS_PARENT_KEY, parentId);
|
|
554
|
+
}
|
|
469
555
|
/**
|
|
470
556
|
* Use focus management
|
|
471
557
|
*/
|
|
472
558
|
function useFocus(options = {}) {
|
|
473
|
-
const
|
|
559
|
+
const inheritedParentId = inject(FOCUS_PARENT_KEY, null);
|
|
560
|
+
const { autoFocus = false, id = `focus-${Math.random().toString(36).slice(2)}`, isActive: isActiveOption = true, delegateFocusTo: delegateFocusToOption = null, trapFocus: trapFocusOption = false } = options;
|
|
561
|
+
const parentIdOption = "parentId" in options ? options.parentId ?? null : inheritedParentId;
|
|
474
562
|
const manager = inject(FOCUS_KEY, null);
|
|
475
563
|
const localFocused = ref(autoFocus);
|
|
476
564
|
const active = isRef(isActiveOption) ? isActiveOption : ref(isActiveOption);
|
|
477
565
|
const parentId = isRef(parentIdOption) ? parentIdOption : ref(parentIdOption);
|
|
566
|
+
const delegateFocusTo = isRef(delegateFocusToOption) ? delegateFocusToOption : ref(delegateFocusToOption);
|
|
567
|
+
const trapsFocus = isRef(trapFocusOption) ? trapFocusOption : ref(trapFocusOption);
|
|
478
568
|
const isFocused = computed(() => {
|
|
479
569
|
if (manager) return manager.isEnabled.value && manager.focusedId.value === id;
|
|
480
570
|
return active.value && localFocused.value;
|
|
481
571
|
});
|
|
482
572
|
const hasFocusedDescendant = computed(() => manager ? manager.hasFocusedDescendant(id) : false);
|
|
573
|
+
const isFocusTrapActive = computed(() => manager?.activeTrapId.value === id);
|
|
483
574
|
const focus = (targetId = id) => {
|
|
484
575
|
if (manager) manager.focus(targetId);
|
|
485
576
|
else if (targetId === id) localFocused.value = true;
|
|
@@ -493,16 +584,27 @@ function useFocus(options = {}) {
|
|
|
493
584
|
manager.register(id, {
|
|
494
585
|
isActive: active.value,
|
|
495
586
|
autoFocus,
|
|
496
|
-
parentId: parentId.value
|
|
587
|
+
parentId: parentId.value,
|
|
588
|
+
delegateFocusTo: delegateFocusTo.value
|
|
497
589
|
});
|
|
590
|
+
if (trapsFocus.value) manager.trapFocus(id);
|
|
498
591
|
watch(active, (enabled) => {
|
|
499
592
|
manager.setActive(id, enabled);
|
|
593
|
+
if (enabled && trapsFocus.value) manager.trapFocus(id);
|
|
500
594
|
if (enabled && autoFocus && !manager.focusedId.value) manager.focus(id);
|
|
501
595
|
}, { immediate: false });
|
|
502
596
|
watch(parentId, (nextParentId) => {
|
|
503
597
|
manager.setParent(id, nextParentId);
|
|
504
598
|
}, { immediate: false });
|
|
599
|
+
watch(delegateFocusTo, (nextDelegate) => {
|
|
600
|
+
manager.setDelegate(id, nextDelegate);
|
|
601
|
+
}, { immediate: false });
|
|
602
|
+
watch(trapsFocus, (trapped) => {
|
|
603
|
+
if (trapped) manager.trapFocus(id);
|
|
604
|
+
else manager.releaseFocusTrap(id);
|
|
605
|
+
}, { immediate: false });
|
|
505
606
|
onUnmounted(() => {
|
|
607
|
+
manager.releaseFocusTrap(id);
|
|
506
608
|
manager.unregister(id);
|
|
507
609
|
});
|
|
508
610
|
}
|
|
@@ -510,6 +612,7 @@ function useFocus(options = {}) {
|
|
|
510
612
|
id,
|
|
511
613
|
isFocused,
|
|
512
614
|
hasFocusedDescendant,
|
|
615
|
+
isFocusTrapActive,
|
|
513
616
|
focus,
|
|
514
617
|
blur
|
|
515
618
|
};
|
|
@@ -521,6 +624,7 @@ function useFocusManager() {
|
|
|
521
624
|
const manager = inject(FOCUS_KEY, null);
|
|
522
625
|
if (!manager) {
|
|
523
626
|
const empty = ref([]);
|
|
627
|
+
const activeId = ref(void 0);
|
|
524
628
|
return {
|
|
525
629
|
enableFocus: () => {},
|
|
526
630
|
disableFocus: () => {},
|
|
@@ -528,8 +632,12 @@ function useFocusManager() {
|
|
|
528
632
|
focusPrevious: () => {},
|
|
529
633
|
focus: (_id) => {},
|
|
530
634
|
hasFocusedDescendant: (_id) => false,
|
|
531
|
-
|
|
532
|
-
|
|
635
|
+
trapFocus: (_id) => {},
|
|
636
|
+
releaseFocusTrap: (_id) => {},
|
|
637
|
+
setDelegate: (_id, _delegateFocusTo) => {},
|
|
638
|
+
activeId,
|
|
639
|
+
focusableIds: empty,
|
|
640
|
+
activeTrapId: activeId
|
|
533
641
|
};
|
|
534
642
|
}
|
|
535
643
|
return {
|
|
@@ -539,8 +647,12 @@ function useFocusManager() {
|
|
|
539
647
|
focusPrevious: manager.focusPrevious,
|
|
540
648
|
focus: manager.focus,
|
|
541
649
|
hasFocusedDescendant: manager.hasFocusedDescendant,
|
|
650
|
+
trapFocus: manager.trapFocus,
|
|
651
|
+
releaseFocusTrap: manager.releaseFocusTrap,
|
|
652
|
+
setDelegate: manager.setDelegate,
|
|
542
653
|
activeId: manager.activeId,
|
|
543
|
-
focusableIds: manager.focusableIds
|
|
654
|
+
focusableIds: manager.focusableIds,
|
|
655
|
+
activeTrapId: manager.activeTrapId
|
|
544
656
|
};
|
|
545
657
|
}
|
|
546
658
|
//#endregion
|
|
@@ -674,6 +786,10 @@ let lastRenderLayouts = [];
|
|
|
674
786
|
function updateLastRenderLayouts(layouts) {
|
|
675
787
|
lastRenderLayouts = layouts;
|
|
676
788
|
}
|
|
789
|
+
/** Read the complete layout snapshot produced by the latest native frame. */
|
|
790
|
+
function getLastRenderLayouts() {
|
|
791
|
+
return lastRenderLayouts;
|
|
792
|
+
}
|
|
677
793
|
/** Look up the latest native layout for an element or component public instance. */
|
|
678
794
|
function getLastRenderLayout(node) {
|
|
679
795
|
const id = node?.id ?? node?.$el?.id;
|
|
@@ -689,6 +805,21 @@ function measureElement(node) {
|
|
|
689
805
|
};
|
|
690
806
|
}
|
|
691
807
|
//#endregion
|
|
808
|
+
//#region src/mouseRouting.ts
|
|
809
|
+
/** Hit-test one normalized mouse packet and route it through the host tree. */
|
|
810
|
+
function routeMouseInput(renderer, root, event, layouts) {
|
|
811
|
+
const target = renderer.hitTest(root, event.x, event.y, layouts);
|
|
812
|
+
if (target) renderer.dispatchInput(target.id, event);
|
|
813
|
+
}
|
|
814
|
+
/** Route first, then publish the packet even when a routed handler throws. */
|
|
815
|
+
function routeAndPublishMouseInput(renderer, root, event, layouts, sink) {
|
|
816
|
+
try {
|
|
817
|
+
if (root) routeMouseInput(renderer, root, event, layouts);
|
|
818
|
+
} finally {
|
|
819
|
+
sink.value = event;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
//#endregion
|
|
692
823
|
//#region src/nativeInput.ts
|
|
693
824
|
/** Accept only key event phases supported by the public Fresco protocol. */
|
|
694
825
|
function normalizeKeyEventType(value) {
|
|
@@ -719,6 +850,92 @@ function normalizeMouseEvent(event) {
|
|
|
719
850
|
} : void 0
|
|
720
851
|
};
|
|
721
852
|
}
|
|
853
|
+
/** Normalize one native input packet into the public Fresco event protocol. */
|
|
854
|
+
function normalizeInputEvent(event) {
|
|
855
|
+
switch (event.eventType) {
|
|
856
|
+
case "resize": return {
|
|
857
|
+
type: "resize",
|
|
858
|
+
width: event.width ?? 0,
|
|
859
|
+
height: event.height ?? 0
|
|
860
|
+
};
|
|
861
|
+
case "paste": return {
|
|
862
|
+
type: "paste",
|
|
863
|
+
text: event.text ?? ""
|
|
864
|
+
};
|
|
865
|
+
case "mouse": return normalizeMouseEvent(event);
|
|
866
|
+
case "focus": return {
|
|
867
|
+
type: "focus",
|
|
868
|
+
focused: event.key === "gained"
|
|
869
|
+
};
|
|
870
|
+
case "compositionstart":
|
|
871
|
+
case "compositionupdate":
|
|
872
|
+
case "compositionend": return {
|
|
873
|
+
type: event.eventType,
|
|
874
|
+
text: event.text ?? "",
|
|
875
|
+
cursor: event.cursor ?? 0
|
|
876
|
+
};
|
|
877
|
+
case "key": {
|
|
878
|
+
const modifiers = event.modifiers ?? {};
|
|
879
|
+
return {
|
|
880
|
+
type: "key",
|
|
881
|
+
key: event.key ?? void 0,
|
|
882
|
+
char: event.char ?? void 0,
|
|
883
|
+
ctrl: modifiers.ctrl ?? false,
|
|
884
|
+
alt: modifiers.alt ?? false,
|
|
885
|
+
shift: modifiers.shift ?? false,
|
|
886
|
+
meta: modifiers.meta ?? false,
|
|
887
|
+
super: modifiers.super ?? false,
|
|
888
|
+
hyper: modifiers.hyper ?? false,
|
|
889
|
+
capsLock: modifiers.capsLock ?? false,
|
|
890
|
+
numLock: modifiers.numLock ?? false,
|
|
891
|
+
eventType: normalizeKeyEventType(event.keyEventType)
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
default: return;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
//#endregion
|
|
898
|
+
//#region src/hitTesting.ts
|
|
899
|
+
function clipsOverflow(value) {
|
|
900
|
+
return value === "hidden" || value === "scroll";
|
|
901
|
+
}
|
|
902
|
+
function clipsDescendants(node) {
|
|
903
|
+
const style = normalizeFrescoStyle(node.props.style);
|
|
904
|
+
return clipsOverflow(style?.overflow ?? style?.overflowX ?? style?.overflowY);
|
|
905
|
+
}
|
|
906
|
+
function containsPoint(layout, clip, x, y) {
|
|
907
|
+
return x >= layout.x && x < layout.x + layout.width && y >= layout.y && y < layout.y + layout.height && x >= clip.left && x < clip.right && y >= clip.top && y < clip.bottom;
|
|
908
|
+
}
|
|
909
|
+
/** Return the deepest topmost live host node under one native-layout coordinate. */
|
|
910
|
+
function hitTest(nodes, root, x, y, layouts) {
|
|
911
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) return void 0;
|
|
912
|
+
const byId = new Map(layouts.map((layout) => [layout.id, layout]));
|
|
913
|
+
const unbounded = {
|
|
914
|
+
left: Number.NEGATIVE_INFINITY,
|
|
915
|
+
top: Number.NEGATIVE_INFINITY,
|
|
916
|
+
right: Number.POSITIVE_INFINITY,
|
|
917
|
+
bottom: Number.POSITIVE_INFINITY
|
|
918
|
+
};
|
|
919
|
+
const visit = (node, ancestorClip) => {
|
|
920
|
+
const layout = byId.get(node.id);
|
|
921
|
+
const clips = clipsDescendants(node);
|
|
922
|
+
const childClip = layout ? {
|
|
923
|
+
left: clips ? Math.max(ancestorClip.left, layout.x) : ancestorClip.left,
|
|
924
|
+
top: clips ? Math.max(ancestorClip.top, layout.y) : ancestorClip.top,
|
|
925
|
+
right: clips ? Math.min(ancestorClip.right, layout.x + layout.width) : ancestorClip.right,
|
|
926
|
+
bottom: clips ? Math.min(ancestorClip.bottom, layout.y + layout.height) : ancestorClip.bottom
|
|
927
|
+
} : ancestorClip;
|
|
928
|
+
for (let index = node.children.length - 1; index >= 0; index -= 1) {
|
|
929
|
+
const child = node.children[index];
|
|
930
|
+
if (!child) continue;
|
|
931
|
+
const target = visit(child, childClip);
|
|
932
|
+
if (target) return target;
|
|
933
|
+
}
|
|
934
|
+
if (!layout || !nodes.has(node.id)) return void 0;
|
|
935
|
+
return containsPoint(layout, ancestorClip, x, y) ? node : void 0;
|
|
936
|
+
};
|
|
937
|
+
return visit(root, unbounded);
|
|
938
|
+
}
|
|
722
939
|
//#endregion
|
|
723
940
|
//#region src/renderer.ts
|
|
724
941
|
/**
|
|
@@ -780,6 +997,30 @@ function detachNode(tree, node) {
|
|
|
780
997
|
notifyUpdate(tree, parent, "children");
|
|
781
998
|
return true;
|
|
782
999
|
}
|
|
1000
|
+
function routedInputEventName(event) {
|
|
1001
|
+
switch (event.type) {
|
|
1002
|
+
case "compositionstart": return "CompositionStart";
|
|
1003
|
+
case "compositionupdate": return "CompositionUpdate";
|
|
1004
|
+
case "compositionend": return "CompositionEnd";
|
|
1005
|
+
default: return `${event.type[0]?.toUpperCase() ?? ""}${event.type.slice(1)}`;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
function callInputHandlers(value, event) {
|
|
1009
|
+
if (typeof value === "function") {
|
|
1010
|
+
value(event);
|
|
1011
|
+
return 1;
|
|
1012
|
+
}
|
|
1013
|
+
if (!Array.isArray(value)) return 0;
|
|
1014
|
+
let handled = 0;
|
|
1015
|
+
for (const handler of value) handled += callInputHandlers(handler, event);
|
|
1016
|
+
return handled;
|
|
1017
|
+
}
|
|
1018
|
+
function dispatchAtNode(node, event, capture, eventName) {
|
|
1019
|
+
const suffix = capture ? "Capture" : "";
|
|
1020
|
+
let handled = callInputHandlers(node.props[`onFrescoInput${suffix}`], event);
|
|
1021
|
+
handled += callInputHandlers(node.props[`on${eventName}${suffix}`], event);
|
|
1022
|
+
return handled;
|
|
1023
|
+
}
|
|
783
1024
|
/**
|
|
784
1025
|
* Renderer options for Fresco
|
|
785
1026
|
*/
|
|
@@ -867,6 +1108,9 @@ function mapElementType(type) {
|
|
|
867
1108
|
case "span": return "text";
|
|
868
1109
|
case "input":
|
|
869
1110
|
case "textinput": return "input";
|
|
1111
|
+
case "raw":
|
|
1112
|
+
case "framebuffer":
|
|
1113
|
+
case "frame-buffer": return "raw";
|
|
870
1114
|
default: return "box";
|
|
871
1115
|
}
|
|
872
1116
|
}
|
|
@@ -901,6 +1145,64 @@ function createRenderer$1(options = {}) {
|
|
|
901
1145
|
disposeNode(tree, node);
|
|
902
1146
|
tree.onMutation();
|
|
903
1147
|
return true;
|
|
1148
|
+
},
|
|
1149
|
+
/**
|
|
1150
|
+
* Return the deepest topmost node under one native-layout coordinate.
|
|
1151
|
+
* Hidden and scroll overflow constrain descendant targeting on each axis.
|
|
1152
|
+
*/
|
|
1153
|
+
hitTest(root, x, y, layouts) {
|
|
1154
|
+
return hitTest(tree.nodes, root, x, y, layouts);
|
|
1155
|
+
},
|
|
1156
|
+
/** Route normalized input through capture, target, and bubble handlers. */
|
|
1157
|
+
dispatchInput(targetId, input) {
|
|
1158
|
+
const target = tree.nodes.get(targetId);
|
|
1159
|
+
if (!target) return void 0;
|
|
1160
|
+
const path = [];
|
|
1161
|
+
for (let node = target; node; node = node.parent) path.push(node);
|
|
1162
|
+
const routed = {
|
|
1163
|
+
input,
|
|
1164
|
+
target,
|
|
1165
|
+
currentTarget: target,
|
|
1166
|
+
phase: "target",
|
|
1167
|
+
defaultPrevented: false,
|
|
1168
|
+
propagationStopped: false,
|
|
1169
|
+
preventDefault() {
|
|
1170
|
+
this.defaultPrevented = true;
|
|
1171
|
+
},
|
|
1172
|
+
stopPropagation() {
|
|
1173
|
+
this.propagationStopped = true;
|
|
1174
|
+
}
|
|
1175
|
+
};
|
|
1176
|
+
const eventName = routedInputEventName(input);
|
|
1177
|
+
let handled = 0;
|
|
1178
|
+
for (let index = path.length - 1; index > 0; index -= 1) {
|
|
1179
|
+
const node = path[index];
|
|
1180
|
+
if (!node) continue;
|
|
1181
|
+
routed.currentTarget = node;
|
|
1182
|
+
routed.phase = "capture";
|
|
1183
|
+
handled += dispatchAtNode(node, routed, true, eventName);
|
|
1184
|
+
if (routed.propagationStopped) break;
|
|
1185
|
+
}
|
|
1186
|
+
if (!routed.propagationStopped) {
|
|
1187
|
+
routed.currentTarget = target;
|
|
1188
|
+
routed.phase = "target";
|
|
1189
|
+
handled += dispatchAtNode(target, routed, true, eventName);
|
|
1190
|
+
handled += dispatchAtNode(target, routed, false, eventName);
|
|
1191
|
+
}
|
|
1192
|
+
if (!routed.propagationStopped) for (let index = 1; index < path.length; index += 1) {
|
|
1193
|
+
const node = path[index];
|
|
1194
|
+
if (!node) continue;
|
|
1195
|
+
routed.currentTarget = node;
|
|
1196
|
+
routed.phase = "bubble";
|
|
1197
|
+
handled += dispatchAtNode(node, routed, false, eventName);
|
|
1198
|
+
if (routed.propagationStopped) break;
|
|
1199
|
+
}
|
|
1200
|
+
return {
|
|
1201
|
+
target,
|
|
1202
|
+
handled,
|
|
1203
|
+
defaultPrevented: routed.defaultPrevented,
|
|
1204
|
+
propagationStopped: routed.propagationStopped
|
|
1205
|
+
};
|
|
904
1206
|
}
|
|
905
1207
|
});
|
|
906
1208
|
}
|
|
@@ -962,6 +1264,43 @@ function isStaticItemNode(node) {
|
|
|
962
1264
|
return node.props.internal_static_item === true || node.props.internalStaticItem === true;
|
|
963
1265
|
}
|
|
964
1266
|
//#endregion
|
|
1267
|
+
//#region src/terminalLifecycle.ts
|
|
1268
|
+
const CI_ENVIRONMENT_KEYS = [
|
|
1269
|
+
"CI",
|
|
1270
|
+
"CONTINUOUS_INTEGRATION",
|
|
1271
|
+
"BUILD_NUMBER",
|
|
1272
|
+
"RUN_ID"
|
|
1273
|
+
];
|
|
1274
|
+
function isTruthyEnvironmentValue(value) {
|
|
1275
|
+
if (!value) return false;
|
|
1276
|
+
return ![
|
|
1277
|
+
"0",
|
|
1278
|
+
"false",
|
|
1279
|
+
"no"
|
|
1280
|
+
].includes(value.toLowerCase());
|
|
1281
|
+
}
|
|
1282
|
+
function isCiEnvironment(env = process.env) {
|
|
1283
|
+
return CI_ENVIRONMENT_KEYS.some((key) => isTruthyEnvironmentValue(env[key]));
|
|
1284
|
+
}
|
|
1285
|
+
/** Resolve whether an application can own the interactive terminal lifecycle. */
|
|
1286
|
+
function detectInteractiveMode(interactive, stdout) {
|
|
1287
|
+
return interactive ?? (stdout.isTTY === true && !isCiEnvironment());
|
|
1288
|
+
}
|
|
1289
|
+
/** Initialize the native terminal modes required by an interactive application. */
|
|
1290
|
+
function initializeTerminal(native, options) {
|
|
1291
|
+
if (typeof native.initTerminalWithOptions === "function") native.initTerminalWithOptions({
|
|
1292
|
+
alternateScreen: options.alternateScreen,
|
|
1293
|
+
bracketedPaste: true,
|
|
1294
|
+
hideCursor: true,
|
|
1295
|
+
mouse: options.mouse,
|
|
1296
|
+
rawMode: true
|
|
1297
|
+
});
|
|
1298
|
+
else if (options.mouse) native.initTerminalWithMouse();
|
|
1299
|
+
else native.initTerminal();
|
|
1300
|
+
native.enableIme?.();
|
|
1301
|
+
native.initLayout();
|
|
1302
|
+
}
|
|
1303
|
+
//#endregion
|
|
965
1304
|
//#region src/app.ts
|
|
966
1305
|
/**
|
|
967
1306
|
* Fresco App - Application instance management
|
|
@@ -1121,33 +1460,12 @@ function updateAppSize(context, width, height) {
|
|
|
1121
1460
|
context.width.value = width;
|
|
1122
1461
|
context.height.value = height;
|
|
1123
1462
|
}
|
|
1124
|
-
const CI_ENVIRONMENT_KEYS = [
|
|
1125
|
-
"CI",
|
|
1126
|
-
"CONTINUOUS_INTEGRATION",
|
|
1127
|
-
"BUILD_NUMBER",
|
|
1128
|
-
"RUN_ID"
|
|
1129
|
-
];
|
|
1130
|
-
function isTruthyEnvironmentValue(value) {
|
|
1131
|
-
if (!value) return false;
|
|
1132
|
-
return ![
|
|
1133
|
-
"0",
|
|
1134
|
-
"false",
|
|
1135
|
-
"no"
|
|
1136
|
-
].includes(value.toLowerCase());
|
|
1137
|
-
}
|
|
1138
|
-
function isCiEnvironment(env = process.env) {
|
|
1139
|
-
return CI_ENVIRONMENT_KEYS.some((key) => isTruthyEnvironmentValue(env[key]));
|
|
1140
|
-
}
|
|
1141
|
-
function detectInteractiveMode(options) {
|
|
1142
|
-
const stdout = options.stdout ?? process.stdout;
|
|
1143
|
-
return options.interactive ?? (stdout.isTTY === true && !isCiEnvironment());
|
|
1144
|
-
}
|
|
1145
1463
|
/**
|
|
1146
1464
|
* Create a Fresco TUI app
|
|
1147
1465
|
*/
|
|
1148
1466
|
function createApp(rootComponent, options = {}) {
|
|
1149
1467
|
const { mouse = false, exitOnCtrlC = true, onError } = options;
|
|
1150
|
-
const interactive = detectInteractiveMode(options);
|
|
1468
|
+
const interactive = detectInteractiveMode(options.interactive, options.stdout ?? process.stdout);
|
|
1151
1469
|
const screenReaderEnabled = ref(options.isScreenReaderEnabled ?? isScreenReaderEnabledByDefault());
|
|
1152
1470
|
const frameDelay = Math.max(1, Math.floor(1e3 / Math.max(1, options.maxFps ?? 30)));
|
|
1153
1471
|
let streamsContext;
|
|
@@ -1169,6 +1487,8 @@ function createApp(rootComponent, options = {}) {
|
|
|
1169
1487
|
let vueApp = null;
|
|
1170
1488
|
let rootElement = null;
|
|
1171
1489
|
let mounted = false;
|
|
1490
|
+
let pendingMount = null;
|
|
1491
|
+
let hasMountedSuccessfully = false;
|
|
1172
1492
|
let running = false;
|
|
1173
1493
|
let needsRender = true;
|
|
1174
1494
|
let appContext = null;
|
|
@@ -1180,6 +1500,8 @@ function createApp(rootComponent, options = {}) {
|
|
|
1180
1500
|
const renderedStaticItems = /* @__PURE__ */ new Map();
|
|
1181
1501
|
let cursorPosition;
|
|
1182
1502
|
let hasCursorOverride = false;
|
|
1503
|
+
let instance;
|
|
1504
|
+
const pluginInstallers = [];
|
|
1183
1505
|
let exitSettled = false;
|
|
1184
1506
|
let resolveExit = null;
|
|
1185
1507
|
let rejectExit = null;
|
|
@@ -1187,26 +1509,38 @@ function createApp(rootComponent, options = {}) {
|
|
|
1187
1509
|
resolveExit = resolve;
|
|
1188
1510
|
rejectExit = reject;
|
|
1189
1511
|
});
|
|
1190
|
-
const
|
|
1191
|
-
|
|
1512
|
+
const renderer = createRenderer$1({
|
|
1513
|
+
lifecycle: options.devtools?.lifecycle,
|
|
1514
|
+
onMutation() {
|
|
1515
|
+
needsRender = true;
|
|
1516
|
+
}
|
|
1192
1517
|
});
|
|
1193
|
-
|
|
1194
|
-
if (
|
|
1518
|
+
function publishRenderMetrics(root, layouts, start) {
|
|
1519
|
+
if (!options.devtools && !options.onRender) return;
|
|
1520
|
+
const metrics = {
|
|
1521
|
+
renderTime: performance.now() - start,
|
|
1522
|
+
nodeCount: treeToRenderNodes(root).length,
|
|
1523
|
+
layoutCount: layouts.length
|
|
1524
|
+
};
|
|
1525
|
+
options.devtools?.recordRender(root, layouts, metrics);
|
|
1526
|
+
options.onRender?.(metrics);
|
|
1527
|
+
}
|
|
1528
|
+
function mount() {
|
|
1529
|
+
if (mounted) return Promise.resolve();
|
|
1530
|
+
if (pendingMount) return pendingMount;
|
|
1531
|
+
pendingMount = Promise.resolve().then(performMount).finally(() => {
|
|
1532
|
+
pendingMount = null;
|
|
1533
|
+
});
|
|
1534
|
+
return pendingMount;
|
|
1535
|
+
}
|
|
1536
|
+
async function performMount() {
|
|
1537
|
+
const app = renderer.createApp(componentFromRoot(rootComponent));
|
|
1538
|
+
for (const install of pluginInstallers) install(app);
|
|
1195
1539
|
const n = interactive ? await loadNative() : null;
|
|
1196
|
-
if (n) {
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
hideCursor: true,
|
|
1201
|
-
mouse,
|
|
1202
|
-
rawMode: true
|
|
1203
|
-
});
|
|
1204
|
-
else if (mouse) n.initTerminalWithMouse();
|
|
1205
|
-
else n.initTerminal();
|
|
1206
|
-
n.enableIme?.();
|
|
1207
|
-
n.initLayout();
|
|
1208
|
-
}
|
|
1209
|
-
const app = createVueApp(componentFromRoot(rootComponent));
|
|
1540
|
+
if (n) initializeTerminal(n, {
|
|
1541
|
+
alternateScreen: options.alternateScreen === true,
|
|
1542
|
+
mouse
|
|
1543
|
+
});
|
|
1210
1544
|
const info = n?.getTerminalInfo() ?? {
|
|
1211
1545
|
width: streamsContext.stdout.columns ?? 80,
|
|
1212
1546
|
height: streamsContext.stdout.rows ?? 24
|
|
@@ -1214,9 +1548,7 @@ function createApp(rootComponent, options = {}) {
|
|
|
1214
1548
|
appContext = createAppContext({
|
|
1215
1549
|
width: info.width,
|
|
1216
1550
|
height: info.height,
|
|
1217
|
-
exit: (value) =>
|
|
1218
|
-
unmount(value);
|
|
1219
|
-
},
|
|
1551
|
+
exit: (value) => void unmount(value),
|
|
1220
1552
|
render,
|
|
1221
1553
|
clear,
|
|
1222
1554
|
waitUntilRenderFlush,
|
|
@@ -1242,10 +1574,18 @@ function createApp(rootComponent, options = {}) {
|
|
|
1242
1574
|
}
|
|
1243
1575
|
vueApp = app;
|
|
1244
1576
|
mounted = true;
|
|
1577
|
+
hasMountedSuccessfully = true;
|
|
1245
1578
|
running = true;
|
|
1246
1579
|
needsRender = true;
|
|
1247
1580
|
eventLoop();
|
|
1248
1581
|
}
|
|
1582
|
+
function use(plugin, ...pluginOptions) {
|
|
1583
|
+
if (pendingMount || hasMountedSuccessfully) throw new Error("Fresco plugins must be installed before the first successful mount");
|
|
1584
|
+
pluginInstallers.push((app) => {
|
|
1585
|
+
app.use(plugin, ...pluginOptions);
|
|
1586
|
+
});
|
|
1587
|
+
return instance;
|
|
1588
|
+
}
|
|
1249
1589
|
async function unmount(errorOrResult) {
|
|
1250
1590
|
if (!mounted) return;
|
|
1251
1591
|
running = false;
|
|
@@ -1282,7 +1622,11 @@ function createApp(rootComponent, options = {}) {
|
|
|
1282
1622
|
return exitPromise;
|
|
1283
1623
|
}
|
|
1284
1624
|
async function waitUntilRenderFlush() {
|
|
1285
|
-
|
|
1625
|
+
if (pendingMount) await pendingMount;
|
|
1626
|
+
await nextTick();
|
|
1627
|
+
if (!needsRender) return;
|
|
1628
|
+
needsRender = false;
|
|
1629
|
+
render();
|
|
1286
1630
|
}
|
|
1287
1631
|
function clear() {
|
|
1288
1632
|
if (!mounted) return;
|
|
@@ -1351,7 +1695,7 @@ function createApp(rootComponent, options = {}) {
|
|
|
1351
1695
|
if (!interactive) {
|
|
1352
1696
|
staticOutput = appendOutput(staticOutput, captureStaticOutput(rootElement, renderedStaticItems));
|
|
1353
1697
|
nonInteractiveOutput = renderPlainOutput(rootElement, staticOutput);
|
|
1354
|
-
|
|
1698
|
+
publishRenderMetrics(rootElement, [], start);
|
|
1355
1699
|
return;
|
|
1356
1700
|
}
|
|
1357
1701
|
if (!native) return;
|
|
@@ -1361,10 +1705,11 @@ function createApp(rootComponent, options = {}) {
|
|
|
1361
1705
|
if (renderNodes.length > 0) {
|
|
1362
1706
|
if (options.debug) streamsContext.stderr.write(`${JSON.stringify(renderNodes, null, 2)}\n`);
|
|
1363
1707
|
native.renderTree(renderNodes);
|
|
1364
|
-
|
|
1708
|
+
const layouts = "getLastRenderLayouts" in native ? native.getLastRenderLayouts() : [];
|
|
1709
|
+
updateLastRenderLayouts(layouts);
|
|
1365
1710
|
applyCursorOverride();
|
|
1366
1711
|
native.flushTerminal();
|
|
1367
|
-
|
|
1712
|
+
publishRenderMetrics(rootElement, layouts, start);
|
|
1368
1713
|
}
|
|
1369
1714
|
} catch (error) {
|
|
1370
1715
|
if (onError) onError(error);
|
|
@@ -1375,58 +1720,31 @@ function createApp(rootComponent, options = {}) {
|
|
|
1375
1720
|
return (await loadNative()).getTerminalInfo();
|
|
1376
1721
|
}
|
|
1377
1722
|
function dispatchEvent(event) {
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
};
|
|
1404
|
-
return;
|
|
1405
|
-
}
|
|
1406
|
-
if (event.eventType === "compositionstart" || event.eventType === "compositionupdate" || event.eventType === "compositionend") {
|
|
1407
|
-
lastCompositionEvent.value = {
|
|
1408
|
-
type: event.eventType,
|
|
1409
|
-
text: event.text ?? "",
|
|
1410
|
-
cursor: event.cursor ?? 0
|
|
1411
|
-
};
|
|
1412
|
-
return;
|
|
1413
|
-
}
|
|
1414
|
-
if (event.eventType === "key") {
|
|
1415
|
-
const modifiers = event.modifiers ?? {};
|
|
1416
|
-
lastKeyEvent.value = {
|
|
1417
|
-
type: "key",
|
|
1418
|
-
key: event.key ?? void 0,
|
|
1419
|
-
char: event.char ?? void 0,
|
|
1420
|
-
ctrl: modifiers.ctrl ?? false,
|
|
1421
|
-
alt: modifiers.alt ?? false,
|
|
1422
|
-
shift: modifiers.shift ?? false,
|
|
1423
|
-
meta: modifiers.meta ?? false,
|
|
1424
|
-
super: modifiers.super ?? false,
|
|
1425
|
-
hyper: modifiers.hyper ?? false,
|
|
1426
|
-
capsLock: modifiers.capsLock ?? false,
|
|
1427
|
-
numLock: modifiers.numLock ?? false,
|
|
1428
|
-
eventType: normalizeKeyEventType(event.keyEventType)
|
|
1429
|
-
};
|
|
1723
|
+
const normalized = normalizeInputEvent(event);
|
|
1724
|
+
if (!normalized) return;
|
|
1725
|
+
options.devtools?.recordInput(normalized);
|
|
1726
|
+
switch (normalized.type) {
|
|
1727
|
+
case "resize":
|
|
1728
|
+
lastResizeEvent.value = normalized;
|
|
1729
|
+
updateAppSize(appContext, normalized.width, normalized.height);
|
|
1730
|
+
break;
|
|
1731
|
+
case "paste":
|
|
1732
|
+
lastPasteEvent.value = normalized;
|
|
1733
|
+
break;
|
|
1734
|
+
case "mouse":
|
|
1735
|
+
routeAndPublishMouseInput(renderer, rootElement, normalized, getLastRenderLayouts(), lastMouseEvent);
|
|
1736
|
+
break;
|
|
1737
|
+
case "focus":
|
|
1738
|
+
lastFocusEvent.value = normalized;
|
|
1739
|
+
break;
|
|
1740
|
+
case "compositionstart":
|
|
1741
|
+
case "compositionupdate":
|
|
1742
|
+
case "compositionend":
|
|
1743
|
+
lastCompositionEvent.value = normalized;
|
|
1744
|
+
break;
|
|
1745
|
+
case "key":
|
|
1746
|
+
lastKeyEvent.value = normalized;
|
|
1747
|
+
break;
|
|
1430
1748
|
}
|
|
1431
1749
|
}
|
|
1432
1750
|
async function eventLoop() {
|
|
@@ -1463,7 +1781,8 @@ function createApp(rootComponent, options = {}) {
|
|
|
1463
1781
|
await new Promise((resolve) => setTimeout(resolve, frameDelay));
|
|
1464
1782
|
}
|
|
1465
1783
|
}
|
|
1466
|
-
|
|
1784
|
+
instance = {
|
|
1785
|
+
use,
|
|
1467
1786
|
mount,
|
|
1468
1787
|
unmount,
|
|
1469
1788
|
waitUntilExit,
|
|
@@ -1472,6 +1791,7 @@ function createApp(rootComponent, options = {}) {
|
|
|
1472
1791
|
clear,
|
|
1473
1792
|
getTerminalInfo
|
|
1474
1793
|
};
|
|
1794
|
+
return instance;
|
|
1475
1795
|
}
|
|
1476
1796
|
/**
|
|
1477
1797
|
* Ink-compatible helper that mounts immediately.
|
|
@@ -1534,6 +1854,6 @@ function renderToString(root, options = {}) {
|
|
|
1534
1854
|
return output;
|
|
1535
1855
|
}
|
|
1536
1856
|
//#endregion
|
|
1537
|
-
export {
|
|
1857
|
+
export { useFocusManager as A, useStdin as C, createFocusManager as D, FOCUS_KEY as E, isScreenReaderEnabledByDefault as F, createAppContext as M, useApp as N, provideFocusScope as O, SCREEN_READER_KEY as P, useStderr as S, useStreamsContext as T, CURSOR_KEY as _, lastMouseEvent as a, STREAMS_KEY as b, render as c, isStaticNode as d, createRenderer$1 as f, updateLastRenderLayouts as g, measureElement as h, lastKeyEvent as i, APP_KEY as j, useFocus as k, renderToString as l, getLastRenderLayout as m, lastCompositionEvent as n, lastPasteEvent as o, treeToRenderNodes as p, lastFocusEvent as r, lastResizeEvent as s, createApp as t, isStaticItemNode as u, createCursorContext as v, useStdout as w, createStreamsContext as x, useCursor as y };
|
|
1538
1858
|
|
|
1539
|
-
//# sourceMappingURL=app-
|
|
1859
|
+
//# sourceMappingURL=app-C_wFlWSV.mjs.map
|